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.
- π 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
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
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)
There are two ways to add search to your Ghost site:
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
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>
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>
- Install the CLI:
npm install -g @fanyangmeng/[email protected]
-
Create
config.json
by usingexample.config.json
as a template. -
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
To keep your search index in sync with your content, you can deploy the webhook handler to your preferred platform:
- Fork this repository
- 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"]
andindexes
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
}'
- Click one of the deployment buttons above
- 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
- Go to Settings β Integrations
- Create/select a Custom Integration
- Give it a name (e.g. "Meilisearch Search")
- 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!
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 |
This project is licensed under the MIT License - see the LICENSE file for details.