Ghost

Connect a Ghost site so that readers who unlock an article receive the full post.

On most platforms, Paperwall hides part of the article that the page has already loaded. Ghost works differently. When a post is members-only, Ghost sends the browser a truncated version, and the remaining text is not present in the page at all.

The Ghost integration therefore reads the full post from your Ghost installation using an admin key, and adds it to the page after a reader unlocks the article. Creating that key is the extra step Ghost requires.

1. Create an admin key in Ghost

  1. In Ghost admin, go to Settings → Integrations.
  2. Select Add custom integration and name it Paperwall.
  3. Copy the Admin API key. It takes the form 640abc…:9f2e…, with two halves separated by a colon. Copy the entire value, including the part after the colon.

You can regenerate this key in Ghost at any time. If you do, replace it in Paperwall as well, or article unlocks will stop working.

2. Connect the key to Paperwall

In the portal, open your site's install settings, select Add a script tag → Ghost, and enter the key together with the URL of your Ghost site.

Paperwall validates the key against your Ghost installation before saving it. A rejected key is not stored, so you can correct it and try again. Once saved, the key is encrypted at rest and is not displayed again.

You can also select I'll do this later. Paperwall records that the site uses Ghost and prompts you again. A Ghost site without a key cannot be published, because a reader who paid would receive an empty article.

3. Install the snippet

The same screen generates the <script> block. In Ghost admin, go to Settings → Code injection and paste it into Site header.

<script
  src="https://assets.paperwall.io/paperwall-bootstrap-v1.4.min.js"
  integrity="sha256-Mq+/rNztnrQlvURnvOyXsMIzsPvI04ucG8ZyXKr8rpo="
  crossorigin="anonymous"
></script>

<script type="application/javascript">
  window.onload = () =>
    buildWall({
      mode: "live",
      wallType: "ghost",
      siteToken: "YOUR_SITE_TOKEN",
    });
</script>

Copy the version generated in the portal rather than the example above: it contains your site token and a verified loader version and integrity hash.

That is the whole configuration. Ghost's page structure is consistent across installations, so the Ghost bundle knows where posts are and which URLs are posts. There is nothing to describe about your site's layout unless your theme departs from Ghost's defaults.

Article detection on Ghost

The Ghost bundle applies these articleFinder defaults:

articleFinder: {
  selector: ".gh-content",
  postUrls: ["^/[^/]+/?$"],
  excludeUrls: [
    "^/(about|contact|privacy)/?$",
    "^/tag/",
    "^/author/",
    "^/ghost/",
  ],
}
  • selector.gh-content is the element Ghost wraps a post body in. Change this only if your theme replaces that wrapper.
  • postUrls — Ghost serves posts at the root as /your-post-slug/, so the include pattern is any single path segment.
  • excludeUrls — because the include pattern is that broad, the exclusions do the real work. Ghost's own taxonomy routes (/tag/…, /author/…) and admin (/ghost/) are covered, along with the static pages a Ghost theme ships with.

Adding your own static pages

A single-segment page that is not a post — /masthead/, /subscribe/, /archive/ — matches postUrls and will show a wall unless you exclude it. Add an articleFinder block to your snippet with an excludeUrls list, restating the defaults you want to keep alongside your own:

articleFinder: {
  excludeUrls: [
    "^/(about|contact|privacy|masthead|subscribe)/?$",
    "^/tag/",
    "^/author/",
    "^/ghost/",
  ],
}

How your values combine with the defaults

The defaults are applied one field at a time. Any of selector, postUrls and excludeUrls you supply is used as given; each one you leave out falls back to the Ghost default. So a theme that renames the post wrapper needs only:

articleFinder: { selector: ".my-post-body" }

and keeps Ghost's URL rules. An empty array counts as omitting the field, since postUrls: [] would otherwise match nothing and silently suppress the wall everywhere.

Note that a field you replace is replaced entirely, not added to — the excludeUrls example above restates Ghost's own patterns for that reason. If you supply some fields but not others, the browser console records which defaults were filled in.

Patterns may be regular expression literals or strings, and are matched unanchored.

Theme

The snippet contains no theme block. The wall takes its name and logo from your Paperwall site settings. You can override either on the wall by adding a theme block, as described under Integrations.

4. Add an article

Add posts by URL, as on any other platform. Paperwall verifies that it can read the post back from Ghost and reports a failure if it cannot. A draft post, or a URL that does not match a Ghost slug, will fail this check.

Ghost members and Paperwall

Both paywalls can run together. Ghost's members paywall continues to work for your subscribers, and Paperwall adds a second route through it for readers who want a single article. When such a reader pays, Paperwall fetches the full post using the admin key and replaces the truncated version on the page.

Troubleshooting empty articles

An article that unlocks but displays no text usually indicates a problem with the admin key. Check the following:

  1. The key is still valid in Settings → Integrations. Regenerating it in Ghost invalidates the copy stored in Paperwall.
  2. The Ghost site URL saved in Paperwall matches the URL your posts are served from.
  3. The post is published rather than a draft.