Skip to content

Add powerful, lightning-fast search to your Ghost blog with Meilisearch. This integration provides everything you need to create a seamless search experience for your readers.

License

Notifications You must be signed in to change notification settings

MFYDev/ghost-meilisearch

Repository files navigation

Ghost Meilisearch Integration

Add powerful, lightning-fast search to your Ghost blog with Meilisearch. This integration provides everything you need to create a seamless search experience for your readers.

demo

✨ Features

  • πŸ” Beautiful Search UI: Accessible, keyboard-navigable search interface that matches your Ghost theme
  • πŸš€ Blazing Fast: Meilisearch delivers sub-50ms search results, even with large content libraries
  • πŸ€– Easy Content Syncing: Simple CLI tool for managing your search index
  • πŸͺ Real-time Updates: Keep your search index in sync with your content via webhooks
  • πŸŒ— Dark/Light Modes: Automatically matches your Ghost theme's color scheme
  • πŸ” Secure: Uses search-only API keys for frontend, admin keys for backend
  • 🍭 Highlight Search Result: Highlight the search result with the exact phrase
  • πŸ“ˆ Improved Plain Text Search Result: Improved plain text search result powered by cheerio

Project Structure

ghost-meilisearch/
β”œβ”€β”€ apps/
β”‚   β”œβ”€β”€ cli/                 # CLI tool
β”‚   └── webhook-handler/     # Webhook handler (Netlify, Vercel & Cloudflare Workers)
β”œβ”€β”€ packages/
β”‚   β”œβ”€β”€ config/              # Configuration utilities
β”‚   β”œβ”€β”€ core/                # Core functionality
β”‚   └── search-ui/           # Search UI component
β”œβ”€β”€ public/                  # Built files for distribution
└── scripts/                 # Build scripts

πŸš€ Quick Start

1. Set Up Meilisearch

You'll need:

  • A Meilisearch instance (cloud or self-hosted)
  • Content API key from Ghost (for syncing content), you can get it by following the guide here
  • Search-only API key from Meilisearch (for the search UI)
  • Writing API key for the index ghost_posts from Meilisearch (for the webhook handler)

2. Add Search to Your Theme

There are two ways to add search to your Ghost site:

Option 1: Replace Ghost's Default Search (Recommended)

Add to your config.[environment].json:

"sodoSearch": {
    "url": "https://cdn.jsdelivr.net/npm/@fanyangmeng/[email protected]/dist/search.min.js"
}

Or set the environment variable:

sodoSearch__url=https://cdn.jsdelivr.net/npm/@fanyangmeng/[email protected]/dist/search.min.js

Option 2: Code Injection

If you're using a managed host like Ghost(Pro), add this to your site's code injection (Settings β†’ Code injection β†’ Site Header):

<script src="https://cdn.jsdelivr.net/npm/@fanyangmeng/[email protected]/dist/search.min.js"></script>

3. Configure the Search UI

Firstly, create a search-only API key in Meilisearch, You can follow the guide here.

Basically, you need to specify the actions to ["search"] and indexes to ["ghost_posts"].

curl \
  -X POST 'MEILISEARCH_URL/keys' \
  -H 'Authorization: Bearer MASTER_KEY' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "description": "Search only key for ghost blog",
    "actions": ["search"],
    "indexes": ["ghost_posts"],
    "expiresAt": null
  }'

Remember, never use the default master API key in the below, it will expose your Meilisearch instance to the public, and allow everyone to add, update and delete documents from your Meilisearch index.

Add this to your site's header code injection:

<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/@fanyangmeng/[email protected]/dist/styles.css">

<script>
  window.__MS_SEARCH_CONFIG__ = {
    meilisearchHost: "https://your-meilisearch-host.com",
    meilisearchApiKey: "your-search-only-api-key",
    indexName: "ghost_posts",
    theme: "system"  // Optional: 'light', 'dark', or 'system'
  };
</script>

4. Initial Content Sync

  1. Install the CLI:
npm install -g @fanyangmeng/[email protected]
  1. Create config.json by using example.config.json as a template.

  2. Initialize and sync:

ghost-meilisearch init --config config.json
ghost-meilisearch sync --config config.json

The CLI tool provides several other commands:

# Index a single post by ID
ghost-meilisearch index <post-id> --config config.json

# Delete a single post from the index by ID
ghost-meilisearch delete <post-id> --config config.json

# Clear all documents from the index
ghost-meilisearch clear --config config.json

5. Set Up Real-Time Updates (Optional)

To keep your search index in sync with your content, you can deploy the webhook handler to your preferred platform:

Deploy to Your Platform

Deploy to Netlify Deploy with Vercel Deploy to Cloudflare Workers

  1. Fork this repository
  2. Create a new API key which will be used by the webhook handler in Meilisearch, and set the actions to ["documents.add", "documents.get", "documents.delete"] and indexes to ["ghost_posts"].
curl \
  -X POST 'MEILISEARCH_URL/keys' \
  -H 'Authorization: Bearer MASTER_KEY' \
  -H 'Content-Type: application/json' \
  --data-binary '{
    "description": "Ghost Meilisearch Webhook Handler API key",
    "actions": ["documents.add", "documents.get", "documents.delete"],
    "indexes": ["ghost_posts"],
    "expiresAt": null
  }'
  1. Click one of the deployment buttons above
  2. Set these environment variables in your platform's dashboard:
GHOST_URL=https://your-ghost-blog.com
GHOST_KEY=your-content-api-key  # From Ghost Admin
GHOST_VERSION=v5.0
MEILISEARCH_HOST=https://your-meilisearch-host.com
MEILISEARCH_API_KEY=your-webhook-api-key  # Meilisearch webhook API key
MEILISEARCH_INDEX_NAME=ghost_posts  # Must match search config
WEBHOOK_SECRET=your-secret-key  # Generate a random string

Set up webhooks in Ghost Admin:

  1. Go to Settings β†’ Integrations
  2. Create/select a Custom Integration
  3. Give it a name (e.g. "Meilisearch Search")
  4. Add these webhooks with your deployed URL:
Platform Webhook URL Format
Netlify https://your-site.netlify.app/.netlify/functions/handler
Vercel https://your-app.vercel.app/api/webhook
Cloudflare Workers https://your-worker.[your-subdomain].workers.dev

Add all four events (Post published, updated, deleted, unpublished) pointing to your webhook URL.

Now your search index will automatically update when you publish, update, or delete posts!

πŸ“¦ Packages

Package Description Latest Version
@fanyangmeng/ghost-meilisearch-search-ui Search interface that matches your Ghost theme 0.5.1
@fanyangmeng/ghost-meilisearch-cli CLI tool for content syncing 0.5.0
@fanyangmeng/ghost-meilisearch-webhook-handler Webhook handler for real-time updates 0.5.1
@fanyangmeng/ghost-meilisearch-config Configuration utilities 0.5.0
@fanyangmeng/ghost-meilisearch-core Core functionality 0.5.0

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.