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

# Typesense Integration (Outpost Hosted)

> Fast, typo-tolerant search for your Ghost posts on a Typesense instance hosted and managed by Outpost.

export const PlanStatus = ({tier, status, beta, deprecated}) => {
  const variants = {
    luna: {
      bg: "#8340B9",
      color: "#ffffff",
      border: "1px solid #8340B9"
    },
    voyager: {
      bg: "#6B2FA0",
      color: "#ffffff",
      border: "1px solid #6B2FA0"
    },
    "space-station": {
      bg: "transparent",
      color: "#8340B9",
      border: "1px solid #8340B9"
    },
    "all-plans": {
      bg: "transparent",
      color: "#525252",
      border: "1px solid #a3a3a3"
    },
    labs: {
      bg: "transparent",
      color: "#a16207",
      border: "1px solid #a16207"
    },
    beta: {
      bg: "transparent",
      color: "#a16207",
      border: "1px solid #a16207"
    },
    "invite-only": {
      bg: "transparent",
      color: "#525252",
      border: "1px solid #a3a3a3"
    },
    bespoke: {
      bg: "transparent",
      color: "#525252",
      border: "1px solid #a3a3a3"
    },
    "outpost-hosted": {
      bg: "transparent",
      color: "#525252",
      border: "1px solid #a3a3a3"
    },
    deprecated: {
      bg: "transparent",
      color: "#b91c1c",
      border: "1px solid #b91c1c"
    }
  };
  const chip = (variant, label) => {
    const s = variants[variant] || variants["all-plans"];
    return <span key={variant + ":" + label} style={{
      display: "inline-flex",
      alignItems: "center",
      padding: "0.15rem 0.55rem",
      fontSize: "0.7rem",
      fontWeight: 700,
      letterSpacing: "0.05em",
      textTransform: "uppercase",
      borderRadius: "3px",
      lineHeight: 1.4,
      whiteSpace: "nowrap",
      backgroundColor: s.bg,
      color: s.color,
      border: s.border
    }}>
        {label}
      </span>;
  };
  const tierLabel = {
    "luna": "Luna",
    "voyager+": "Voyager+",
    "voyager-luna": "Voyager + Luna",
    "space-station+": "Space Station+",
    "all-plans": "All plans"
  };
  const tierVariant = {
    "luna": "luna",
    "voyager+": "voyager",
    "voyager-luna": "voyager",
    "space-station+": "space-station",
    "all-plans": "all-plans"
  };
  const statusLabel = {
    "labs": "Labs",
    "invite-only": "Invite-only",
    "bespoke": "Bespoke",
    "deprecated": "Deprecated",
    "outpost-hosted": "Outpost Hosted"
  };
  return <span style={{
    display: "inline-flex",
    gap: "0.4rem",
    flexWrap: "wrap",
    alignItems: "center",
    margin: "0 0 1.25rem 0"
  }}>
      {tier && chip(tierVariant[tier], tierLabel[tier])}
      {status && chip(status, statusLabel[status])}
      {beta && chip("beta", "Beta")}
      {deprecated && chip("deprecated", "Deprecated")}
    </span>;
};

<PlanStatus tier="voyager+" status="outpost-hosted" />

<Info>
  Typesense is hosted and managed by Outpost. There is no bring-your-own-server option, and there are no server credentials to enter on your side.
</Info>

[Typesense](https://typesense.org) is an open-source, typo-tolerant search engine. Outpost runs the Typesense cluster, indexes your Ghost posts into it, and exposes the search results to your theme. It's the recommended search integration for all new publications.

## How indexing works

Outpost keeps your search index in sync with Ghost automatically. You set up one or more **collections** per site: each collection is a separate searchable index that pulls in posts, pages, authors, and tags filtered by the tag rules you choose. Your data lives in its own space and isn't visible to other publications on the cluster.

### Collections and how to use them

For most sites, **one collection that searches everything is enough**. Visitors type a query, see results across all your content, done.

If you publish a lot of distinct content types (posts plus podcast episodes plus videos, for example), you can add a separate collection for each one. Each collection becomes a **tab in the search popup**, and the label on the tab is the collection's **Public name** (so "Articles", "Podcasts", "Videos"). Visitors can stay in the default tab to search everything, or click a specific tab to narrow to just that content type.

<Note>
  Tabs only appear once you have two or more collections. With a single collection, the search popup hides the tab bar, so visitors never see the Public name at all. The one-click setup creates one collection named "Posts", and that name stays inside your settings.
</Note>

Each collection has its own tag rules, so a "Podcasts" collection might include only posts tagged `podcast`, while an "Articles" collection excludes that tag. You can also control whether pages, author profiles, and tag pages are indexed into each collection.

<Note>
  On phones, the search popup opens as a full-screen overlay with a sticky search bar at the top, so it stays in reach as visitors scroll. When you have multiple collections, the tabs become swipeable so visitors can move between content types with a flick.
</Note>

### What gets indexed

For each post or page, Outpost stores the title, the body content (with formatting stripped), the excerpt, the slug, the feature image, the URL, the authors, and the tags. Authors and tags can be indexed as their own results too, so a search for an author name can surface that author's page alongside their posts.

What stays out of search:

* **Email-only posts, and anything that isn't published in Ghost.** Drafts and scheduled posts never reach search.
* **Anything tagged `#hide` or `#no-index`.** Every new collection starts with those two tags in **Exclude posts tagged** and **Exclude pages tagged**, so tagging a post or a page with either one in Ghost keeps it out of search. You can change those lists on the collection at any time.
* **Posts whose tags don't match the collection's rules.** A collection set to **Choose by tag** takes only the posts carrying one of its listed tags.
* **Authors with no published posts**, and internal tags (any tag whose name starts with `#`) when a collection indexes tag pages.

Paid posts are a different case: they are included by default. See [Paid posts in search](#paid-posts-in-search).

### Paid posts in search

Paid (members-only) posts are searchable by default. In the collection editor, the checkbox **Include paid (members-only) posts** is ticked both for the one-click setup and for every collection you create yourself.

What that means for your readers:

* A paid post can be found by anyone, signed in or not. The search matches on the post's title, tags, authors, excerpt, and full body text.
* The result shows the title, the excerpt, and whichever details you have turned on for that collection. The excerpt is the post's custom excerpt in Ghost, or the first 30 words of the post when there is no custom excerpt.
* The full body of the post is not sent to the reader's browser. It is matched against, but the words shown in the result come from the title and the excerpt.

<Warning>
  If you gate posts and don't want their titles and opening words surfaced to everyone, open the collection on the **Collections** tab, untick **Include paid (members-only) posts**, and save. Any post whose Ghost visibility is not public is then left out of the index, both when the index is rebuilt and when a post changes in Ghost. Saving that change starts a rebuild, so plan for the [re-index](#re-indexing) it triggers.
</Warning>

### When indexing happens

Outpost re-indexes automatically whenever something changes in Ghost:

* **A post or page is published, updated, or unpublished**: the document is added, refreshed, or removed in every collection it belongs to.
* **A tag or author is edited**: the matching tag or author entry is updated in collections that include them.
* **A post or page is deleted**: it's removed from search.

These updates run in the background within seconds of the change in Ghost. There's no manual step to keep search fresh.

### Full re-index

A full re-index runs in three situations:

1. **When search is first turned on**: every collection is built from scratch.
2. **When you click Re-index on a collection**: that one collection is wiped and rebuilt.
3. **When you save a change to what a collection includes**: every collection on the site is wiped and rebuilt. Changes to how results look are saved without a rebuild.

A re-index pulls every matching post and page from your Ghost site in batches and rebuilds from scratch. You'll get an email when it finishes. Use it after a bulk import, a large tag cleanup, or any time a collection looks out of sync.

## How the Boost function works

By default, search results are sorted newest first. **Boost** lets you override that order by giving certain tags extra weight, so posts on the topics you care most about rank above otherwise-equivalent results.

### Configuring boosts

Open the **TypeSense** card from **Integrations and Core Connections → Integrations**, open the collection you want to tune from the **Collections** tab, and in its **Ranking** section click **Boost results by tag**. Add a row for each tag you want to weight, pick the tag from the dropdown, and set a boost amount between **0 and 10**. Any tag you don't list stays at the default of 0.

> *Example: if a regular post and a podcast post are scoring about the same on relevance, give the `podcast` tag a boost of 5 to push podcast results to the top.*

### How boost values are applied

Each post's boost score is the **sum of the boost amounts on its tags**. A post tagged with both `podcast` (boost 5) and `featured` (boost 3) ends up with a score of 8. Posts with higher boost scores rank above lower ones, and recency breaks ties.

Boost is calculated when the post is indexed, not when a visitor searches. That means **after changing a boost value, click Re-index on the collection** so the new weights are applied to every existing post. Posts edited in Ghost after the change will pick up the new values on their own.

If you haven't configured any boosts, search falls back to the default "newest first" ordering.

### What searches match against

Searches look at the title, tags, authors, body content, and excerpt of each document, with typo tolerance built in.

## How results look

Two layers control how each search result is displayed: a site-wide **Default display** that applies everywhere, and optional per-collection overrides for any collection that should look different.

### Default display

On the **Default display** tab, set how results appear across every collection:

* **Match my CTA design**: take the corner rounding from your CTA design defaults. Uncheck it to set the **Border radius** yourself. The accent color and font always come from your Ghost site, whether this is checked or not.
* **Color mode**: Light, Dark, or Auto. Auto reads your Ghost theme's background color and picks the light or dark palette to match it.
* **Border radius**: how rounded the search panel, the search box, and the collection tabs are. Only shown when **Match my CTA design** is unchecked.
* **Search title**, **Search placeholder**, and **No-results message**: the wording visitors see in the search box.
* **Result content**: choose whether results show the featured image, a matching snippet, the primary author, and the primary tag, and whether to hide internal tags (those starting with `#`).
* **Default image when a result has none**: upload one image to stand in for results without a featured image. Leave it empty and those results fall back to your site logo. This image applies to every collection unless a collection sets its own.

Click **Save search design** to apply.

The colors themselves are not set here. Backgrounds and text follow the light or dark palette, and the accent used for matched terms, result labels, and the selected collection tab follows your Ghost accent color. To change any of those, see [Styling the Search Popup](/developers/search-styling).

### Per-collection display

Every collection follows your Default display settings unless you override it. To make one collection look different, open it from the **Collections** tab, find its **Display** section, and click **Customize display for this collection**. The overrides apply to that collection only and cover the same options as Default display, including its own **Default image when a result has none**, which falls back to the site-wide image (and then your site logo) when empty.

The Display section also has a **Never show these tags** list: enter tags you don't want shown in a result's metadata, even when a post carries them. Wildcards work, so `#megaphone_*` hides every tag that starts with `#megaphone_`.

### Result labels

In a collection's **Result labels** section, turn on **Show a label on each result** to add a small badge to results based on their tags or URL: for example, label anything tagged `#episode` as **Video**. Add a rule for each label, then set the label for **Everything else** to cover results that don't match a rule. Labels are specific to the collection you set them on.

## Typesense vs. Algolia

|                   | Typesense                       | Algolia                                       |
| ----------------- | ------------------------------- | --------------------------------------------- |
| Hosting           | Outpost-hosted                  | Algolia-hosted (BYO Algolia account)          |
| Cost to publisher | Included                        | Algolia's published plans                     |
| Indexing          | Automatic on every Ghost change | Automatic on every Ghost change               |
| Recommended for   | New publications                | Publications with an existing Algolia account |

## Setup

Search is switched on for your site by Outpost. Email **[support@outpost.pub](mailto:support@outpost.pub)** to ask for it. After that you manage search yourself from **Integrations and Core Connections → Integrations**, on the **TypeSense** card.

The panel is organized into three tabs, and it opens on the first one:

* **Collections**: create and tune each searchable index, including its tag rules, per-collection display, result labels, and ranking.
* **Default display**: set how results look across your whole site, including a fallback image for results that have none.
* **Placement**: choose what opens search on your site and how results are shown.

There's nothing to configure on the Typesense side; Outpost runs the cluster.

<Note>
  Only Outpost can connect search the first time, so the TypeSense entry doesn't appear in your Add Integration menu. Once search is on, the TypeSense card is available to any admin on your site, and collections, display, placement, and re-indexing are all yours to manage.
</Note>

### Turning search on with the defaults

Before search is connected, the **Collections** tab leads with a panel headed **Recommended: start with the defaults**. **Turn on with defaults** is the normal route: one click connects search and sets up everything a standard Ghost site needs.

The defaults it applies:

* One collection with the Public name **Posts**, set to **All posts**, with **Include paid (members-only) posts** turned on and `#hide` and `#no-index` in **Exclude posts tagged**.
* Pages, author pages, and tag pages left out.
* No tag boosts.
* **Search trigger** set to **Ghost's default search button** and **Show results as** set to **Popup**, so search opens from the button already in your theme.
* Results showing the featured image, the author, the matching text, an excerpt, and one tag. The date, the ordering dropdown, and result labels are off.

Search is live as soon as the setup finishes. Results appear as your posts are indexed, and Outpost emails you when indexing is complete. Your Ghost site has to be connected before search can be turned on, because search follows your Ghost content as it changes.

Nothing else is required. When you want to go further, change the wording on **Default display**, add more collections, add tag boosts, or change **Placement**. To change the colors, see [Styling the Search Popup](/developers/search-styling).

<Warning>
  The default setup includes your paid posts, so anyone can find a members-only post in search and read its excerpt. If that isn't what you want, see [Paid posts in search](#paid-posts-in-search).
</Warning>

### Setting up collections yourself

If you'd rather choose everything up front, use **Set up manually** on the same panel. It opens the collection editor with the same starting values, so you can set the **Public name**, decide what the collection includes, and adjust the tag rules before anything is indexed.

Once search is connected, that panel is replaced by the **New collection** button, which is how you add every collection after the first.

### Choosing how search opens

The **Placement** tab has two controls. Both arrive already set to the standard Ghost arrangement, a popup opened by your theme's own search button, so most sites never need to change them.

**Search trigger** sets what a visitor clicks to open search:

* **Ghost's default search button**: the right choice for most publishers. The search button already in your Ghost theme keeps working, and Outpost opens the Typesense popup behind it. No theme edits needed.
* **Custom element**: for a theme with a non-standard search trigger, or to open search from a specific button, link, or icon. A **Trigger selector** field appears; enter a CSS selector such as `#search-btn`, `.site-header .search`, or `[data-open-search]`. Every matching element opens search when clicked.

**Show results as** sets where results appear:

* **Popup**: results open in an overlay when a visitor triggers search. This is the default.
* **Embedded in a container**: render the search box and results inline on the page, for example on a dedicated `/search` page. A **Container selector** field appears; enter a selector for the element to mount search inside.

Click **Save placement** to apply.

## Re-indexing

Index updates run automatically when Ghost content changes. If a collection looks out of sync (for example, after a bulk import, a large tag re-organization, or a change to boost settings), open the collection in the TypeSense panel and click **Re-index**. The button appears once the collection has been saved. The re-index runs in the background and emails you when it completes.

Saving a collection can also start a rebuild. When you change what a collection includes, Outpost asks first, in a dialog headed **Save and re-index?** with a **Re-index and save** button. That rebuild covers every collection on the site, not only the one you edited, so treat it as a full rebuild if you run more than one collection. Changes that only affect how results look are saved without it.

A re-index wipes the index first and then rebuilds it post by post, so **search returns zero results at the start, then partial results, until the rebuild finishes**. For most sites this only lasts a few moments. But if you have **more than \~2,000 posts**, or your site is in the middle of a traffic peak, plan to run the re-index during a quieter part of the day: tens of thousands of posts can take a while to repopulate, and visitors searching mid-rebuild will see incomplete results.

## Related features

<CardGroup cols={2}>
  <Card title="Algolia Integration" icon="magnifying-glass" href="/integrations/algolia">
    Alternative search integration for publications already on Algolia.
  </Card>

  <Card title="Ghost Integration" icon="ghost" href="/integrations/ghost">
    Ghost is the source of post content that gets indexed for search.
  </Card>

  <Card title="Styling the Search Popup" icon="palette" href="/developers/search-styling">
    Match the popup to your theme with CSS variables and class hooks.
  </Card>
</CardGroup>

## FAQ

<AccordionGroup>
  <Accordion title="How do I turn search on?">
    Email **[support@outpost.pub](mailto:support@outpost.pub)** and Outpost switches it on for your site. The setup itself is one click: on the **Collections** tab, the panel headed **Recommended: start with the defaults** has a **Turn on with defaults** button that creates a single **Posts** collection covering all your posts, opens search as a popup from your theme's existing search button, and leaves out pages, author pages, and tag pages. **Set up manually** opens the collection editor instead, for choosing all of that yourself. Your Ghost site has to be connected before search can be turned on.
  </Accordion>

  <Accordion title="Do I need my own Typesense account?">
    No. Outpost runs the Typesense cluster and includes it as part of your subscription.
  </Accordion>

  <Accordion title="Can I bring my own Typesense server?">
    Not currently. Search is delivered through Outpost's hosted Typesense cluster.
  </Accordion>

  <Accordion title="Do I need to edit my Ghost theme to add search?">
    No, not for most setups. **Search trigger** is already set to **Ghost's default search button**, so the search button in your theme keeps working and opens the Typesense popup instead. Change it on the **Placement** tab only if your theme uses a non-standard search trigger, using the **Custom element** option.
  </Accordion>

  <Accordion title="Are my paid posts findable in search?">
    Yes, by default. **Include paid (members-only) posts** is on for the one-click setup and for every new collection, so anyone can find a members-only post in search and read its excerpt, which is the custom excerpt from Ghost or the first 30 words of the post. The full body of the post is not sent to the reader's browser. To leave paid posts out, open the collection on the **Collections** tab, untick **Include paid (members-only) posts**, and save. Saving that change starts a rebuild of the index.
  </Accordion>

  <Accordion title="When should I add a second collection?">
    Add another collection when you publish a distinct content type that visitors might want to search on its own: podcast episodes, video posts, a separate research library. Each collection becomes a tab in the search popup, so visitors can search everything by default or narrow to one type. For most sites, a single collection is the right answer.
  </Accordion>

  <Accordion title="Will visitors see a tab for my collection?">
    Only when you have two or more collections. The search popup hides the tab bar while there is a single collection, so the default **Posts** collection created by the one-click setup is never labelled on screen.
  </Accordion>

  <Accordion title="How do I trigger a full re-index?">
    Re-indexing is automatic on Ghost changes. For a full rebuild of a single collection, use the **Re-index** button on the collection in the TypeSense panel.
  </Accordion>

  <Accordion title="Will visitors see broken search while a re-index runs?">
    Yes, briefly. The index is wiped first and then rebuilt post by post, so searches return zero results at the start, then partial results until the rebuild finishes. For most sites this only lasts a few moments. If you have more than around 2,000 posts or your site is busy, schedule the re-index for an off-peak time.
  </Accordion>

  <Accordion title="I changed a boost value but search results haven't moved.">
    Boost is calculated when a post is indexed, not when a visitor searches. After changing a tag's boost amount, click **Re-index** on the collection so the new weights are applied to every existing post. Posts you edit in Ghost after the change will pick up the new values on their own.
  </Accordion>

  <Accordion title="What's the maximum boost value?">
    Each tag can be boosted by a whole number from 0 to 10. A post's overall boost is the sum of all its matching tag boosts, so multiple boosted tags stack.
  </Accordion>

  <Accordion title="What if I want to use Algolia instead?">
    See the [Algolia Integration](/integrations/algolia) page. Typesense is recommended for new publications; Algolia fits publications that already have an Algolia account in place.
  </Accordion>
</AccordionGroup>
