> ## Documentation Index
> Fetch the complete documentation index at: https://docs.beyondwords.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Ghost

The BeyondWords Ghost plugin allows you to automatically generate and embed audio and video versions of your posts.

<Tip>
  [Audio](/docs-and-guides/content/audio)/[video](/docs-and-guides/content/video) format, [script templates](/docs-and-guides/tools/generate-scripts), [video templates](/docs-and-guides/content/video), [voices](/docs-and-guides/voices/overview), and [player settings](/docs-and-guides/distribution/player/player-settings) are controlled by your BeyondWords project defaults unless you configure otherwise in the dashboard. You can also set up other distributions for your audio and video content, or configure the integration via the [Ghost API](/api-reference/ghost/show).
</Tip>

## How it works

Ghost is a **server-side** integration—unlike [Magic Embed](/docs-and-guides/integrations/magic-embed), content is pushed from Ghost to BeyondWords when posts change, not fetched from the visitor's browser.

1. You connect Ghost to BeyondWords by saving your Ghost **Admin API Key** and **API URL** in the dashboard. BeyondWords registers webhooks on your Ghost site for `post.added` and `post.edited` events.
2. When you publish or update a post, Ghost sends the post payload to BeyondWords. The post's `title` and `html` become the content item's title and body; the Ghost post ID becomes `source_id` and the post URL becomes `source_url`.
3. BeyondWords processes the HTML with `auto_segment` (applying [content filters](/docs-and-guides/integrations/content-extraction#filters) if configured) and generates audio/video.
4. The player script in your theme's **Site footer** loads on each post page, identifies the content by page URL, and embeds the player once generation is complete.

On first publish, the player may not appear until audio/video generation finishes—usually within a few minutes.

## Connect Ghost to BeyondWords

<Steps>
  <Step title="Create a custom integration in Ghost">
    In Ghost Admin, go to **Settings → Integrations**.

    Click **Add custom integration**, name it **BeyondWords**, then click **Add**.

    Copy the **Admin API Key** and **API URL**—you'll need both in the next step.
  </Step>

  <Step title="Save credentials in BeyondWords">
    Go to **Settings → Integrations → Ghost** in your BeyondWords [project dashboard](/docs-and-guides/get-started/projects).

    Paste the **API URL** and **Admin API Key** from Ghost, then click **Save changes**.

    BeyondWords validates the credentials and registers webhooks on your Ghost site automatically. You should see a success message confirming the connection.
  </Step>

  <Step title="Copy the embed code">
    In the **Embed code** dropdown on the same page, select the format you want on post pages:

    | Option            | Player shows                                                                                           |
    | ----------------- | ------------------------------------------------------------------------------------------------------ |
    | **Audio article** | [Audio](/docs-and-guides/content/audio) version of the full article                                    |
    | **Audio summary** | Audio version of the [script](/docs-and-guides/tools/generate-scripts) (if your project generates one) |
    | **Video article** | [Video](/docs-and-guides/content/video) version of the full article                                    |
    | **Video summary** | Video version of the [script](/docs-and-guides/tools/generate-scripts) (if your project generates one) |

    Click the copy icon alongside the embed code.
  </Step>

  <Step title="Add the embed code to Ghost">
    In Ghost Admin, go to **Settings → Code injection** and open the editor.

    In the **Site footer** section, paste the embed code. Take care not to interfere with any existing scripts.

    Set `target` to the CSS selector where the player should appear in your theme—for example `.post-full-content`, `article`, `article header`, or `.content`. The dashboard embed defaults to `.post-full-content`, which works for most Ghost themes.

    Click **Save**.
  </Step>

  <Step title="Publish a post">
    Publish or update a post in Ghost as normal. The post appears in your BeyondWords dashboard and audio/video generation starts automatically.

    Once generation completes, the player loads on the post page.
  </Step>
</Steps>

## What Ghost sends to BeyondWords

On each `post.added` or `post.edited` webhook, BeyondWords maps the Ghost post to a content item:

| Ghost field                      | BeyondWords field                    |
| -------------------------------- | ------------------------------------ |
| Post `id`                        | `source_id`                          |
| Post `url`                       | `source_url`                         |
| Post `title`                     | Title                                |
| Post `html`                      | Body (processed with `auto_segment`) |
| Post `feature_image`             | Feature image                        |
| First author name                | Author                               |
| `published_at` (or `updated_at`) | Publish date                         |

Draft posts are not published to the player. Posts tagged with `#beyondwords-skip` are treated as unpublished—see [Skip generation for specific posts](#skip-generation-for-specific-posts) below.

## Player placement

The embed code uses the [JavaScript SDK](/docs-and-guides/distribution/player/installation/javascript-sdk) (`BeyondWords.Player`). If you don't pass a content identifier, the player matches content using the current page URL (`window.location.href`), which corresponds to the post's `source_url`.

Set `target` to a CSS selector for the element the player should inject into. The player is inserted as the first child of that element.

If your theme uses a non-standard layout, inspect the post template and choose a selector that wraps the article header or body. You can also add a dedicated container in your theme:

```html theme={null}
<div class="beyondwords-target"></div>
```

Then set `target: '.beyondwords-target'` in the embed code.

For advanced theme integration, the [`@beyondwords/ghost-helper`](https://www.npmjs.com/package/@beyondwords/ghost-helper) package can auto-detect the target element on Ghost post and page templates. The dashboard embed code uses the player SDK directly, which is the recommended approach for most sites.

Customize player appearance in **Distribution → Player** in your dashboard, or pass additional [player properties](/docs-and-guides/distribution/player/developer-guides/player-properties) in the embed script.

## Fine-tuning your integration

* [Content extraction](/docs-and-guides/integrations/content-extraction): [Content filters](/docs-and-guides/integrations/content-extraction#filters) apply to post HTML sent via webhooks. Use filters to exclude newsletter blocks, related posts, or other recurring elements.
* [Data attributes](/docs-and-guides/integrations/data-attributes): Add `data-beyondwords-*` attributes to your Ghost theme templates or post HTML for metadata and per-paragraph control.
* [Player settings](/docs-and-guides/distribution/player/player-settings): Configure widget style, colors, and behavior.
* [Generate scripts](/docs-and-guides/tools/generate-scripts): Required if you use an **Audio summary** or **Video summary** embed code variant.

## Skip generation for specific posts

To prevent a post from generating or updating audio/video:

1. In the Ghost post editor, open the **Post settings** side panel
2. In the **Tags** field, add the internal tag `#beyondwords-skip`
3. Publish your post as usual

Effects:

* **New posts** with this tag are not ingested for generation.
* **Existing posts** with this tag are marked unpublished—the player will not load. Future post edits will not trigger regeneration.
* Remove the tag and re-publish to resume normal sync.

## FAQs

<AccordionGroup>
  <Accordion title="Do I need to configure webhooks manually in Ghost?">
    No. When you save your Ghost credentials in the BeyondWords dashboard, webhooks for `post.added` and `post.edited` are registered on your Ghost site automatically.
  </Accordion>

  <Accordion title="How does the player find the right content for each post?">
    The embed script identifies content by the post page URL. BeyondWords stores each Ghost post's canonical URL as `source_url` when the webhook fires. As long as the URL in the visitor's browser matches, the player loads the correct audio or video.
  </Accordion>

  <Accordion title="Can I embed audio summary or video summary?">
    Yes—choose **Audio summary** or **Video summary** in the embed code dropdown. Your project must generate scripts for content items (configure in **Content → Preferences** or per-item in the [Editor](/docs-and-guides/tools/editor)). The Ghost integration only sends the post body; script generation happens on the BeyondWords side.
  </Accordion>

  <Accordion title="What happens if I edit a post in the BeyondWords Editor?">
    Editing in the [Editor](/docs-and-guides/tools/editor) switches the content item to `manual_segment` processing and disables automatic CMS updates (`auto_segment_updates_enabled`). Ghost webhook updates for that post will be blocked until you re-enable automatic updates or send a new API update with `type` set to `auto_segment`. Prefer [content filters](/docs-and-guides/integrations/content-extraction#filters) over Editor edits if you want Ghost updates to keep syncing.
  </Accordion>

  <Accordion title="How do content filters work with Ghost?">
    Dashboard content filters apply to the post HTML sent via webhooks, because Ghost content is processed with `auto_segment`. Configure filters in **Settings → Extraction → Filters**. See the [content extraction guide](/docs-and-guides/integrations/content-extraction#when-filters-apply).
  </Accordion>

  <Accordion title="How do I customize the player?">
    Go to **Distribution → Player** in your BeyondWords project dashboard for widget style, colors, and default behavior.

    For per-site customization, edit the embed script in Ghost **Code injection**—any [player property](/docs-and-guides/distribution/player/developer-guides/player-properties) can be passed to `BeyondWords.Player` in the `onload` handler.
  </Accordion>

  <Accordion title="The player isn't showing on my post—what should I check?">
    * Confirm audio/video generation has completed in the BeyondWords dashboard
    * Check the post is published and does not have the `#beyondwords-skip` tag
    * Verify the embed code is in **Site footer** code injection and `target` matches an element in your theme
    * Open the browser console for JavaScript errors—a missing `target` element will prevent the player from loading
  </Accordion>
</AccordionGroup>

## Getting help

If you encounter issues or have questions, [contact support](/docs-and-guides/support/get-support). Include your Ghost site URL, a sample post link, and whether the post appears in your BeyondWords dashboard.
