> ## 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 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 collection 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.

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.

Email-only posts and unpublished drafts are skipped. Posts are only indexed into a collection if their tags match that collection's rules.

### 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 reindex

A full reindex runs in two situations:

1. **When you first connect Typesense** — every collection is built from scratch.
2. **When you click "Reindex" on a collection** — that collection is wiped and rebuilt.

A reindex pulls every matching post and page from your Ghost site in batches and rebuilds the collection 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 **Integrations → Typesense**, 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 Reindex 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** — reuse the look of your CTA design settings so search matches the rest of your site.
* **Color mode** — Light, Dark, or Auto (follows the visitor's system setting).
* **Border radius** — how rounded the search box and result cards are.
* **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.

### 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

The Typesense integration is organized into three tabs:

* **Collections** — create and tune each searchable index: 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. The one required step is on the **Placement** tab: telling Outpost what triggers search.

### Choosing how search opens

The **Placement** tab has two controls.

**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.

## Reindexing

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 — click **Reindex** on the collection in the Typesense integration panel. The reindex runs as a background job and emails you when it completes. For cluster-wide rebuilds, email **[support@outpost.pub](mailto:support@outpost.pub)**.

A reindex wipes the collection 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 reindex 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>
</CardGroup>

## FAQ

<AccordionGroup>
  <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. On the **Placement** tab, set **Search trigger** to **Ghost's default search button** and Outpost replaces Ghost's built-in search with the Typesense popup automatically. Use the **Custom element** option only if you want to trigger search from a non-standard element on your site.
  </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="How do I trigger a full reindex?">
    Reindexing is automatic on Ghost changes. For a full rebuild of a single collection, use the **Reindex** button on the collection in the Typesense integration panel. For a cluster-wide rebuild, email [support@outpost.pub](mailto:support@outpost.pub).
  </Accordion>

  <Accordion title="Will visitors see broken search while a reindex runs?">
    Yes — briefly. The collection 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 reindex 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 **Reindex** 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>
