strapi-plugin-algolia-sync
v1.0.0
Published
Algolia search integration plugin for Strapi v5 — auto-syncs content via lifecycle hooks, supports bulk reindex from the admin panel.
Maintainers
Readme
strapi-plugin-algolia
Strapi v5 plugin that syncs content to Algolia automatically via lifecycle hooks, with a manual "Index all items" button in the admin panel.
Features
- Auto-sync on publish, unpublish, and delete via lifecycle hooks
- Bulk reindex button in content-manager list view (per collection type)
- Optional full reindex on boot
- Multi-locale support
- Domain/tag filtering support
- Rich-text (CKEditor) HTML stripping
- Configurable per-content-type: index name, title field, URL pattern
Installation
Option A — Local path (recommended for development)
Copy or symlink this folder anywhere, then reference it by path.
Option B — npm (after publishing)
npm install strapi-plugin-algoliaSetup
1. Register the plugin in config/plugins.js
// config/plugins.js
module.exports = ({ env }) => ({
algolia: {
enabled: true,
resolve: '../strapi-plugin-algolia', // path to plugin folder (local) OR omit for npm
config: {
// Algolia credentials — prefer env vars over hardcoding
appId: env('ALGOLIA_APP_ID', ''),
apiKey: env('ALGOLIA_ADMIN_API_KEY', ''),
// Optional: prefix every index name (e.g. 'prod_', 'staging_')
indexPrefix: env('ALGOLIA_INDEX_PREFIX', ''),
// Run a full reindex every time Strapi boots (default: false)
reindexOnBoot: env.bool('ALGOLIA_REINDEX_ON_BOOT', false),
// Index name shared by all single-type content types (default: 'static_pages')
singleTypeIndexName: 'static_pages',
// UIDs to never index, even if listed in contentTypes
skipContentTypes: [
'api::tag.tag',
'api::category.category',
],
// Content types to index
contentTypes: [
// Collection type — each entry becomes its own Algolia record
{
uid: 'api::article.article',
indexName: 'articles', // Algolia index name
titleField: 'title', // field (dot-notation ok, e.g. 'banner.title')
urlPattern: '/articles/{slug}', // {slug} → entry.slug
},
// Collection type with a static title
{
uid: 'api::team-member.team-member',
indexName: 'team',
titleField: 'name',
urlPattern: '/about/team/{slug}',
},
// Single type — goes into the shared singleTypeIndexName index
{
uid: 'api::home-page.home-page',
staticTitle: 'Home', // hard-coded; no titleField needed
urlPattern: '/',
},
{
uid: 'api::about-page.about-page',
staticTitle: 'About',
urlPattern: '/about',
},
],
},
},
});2. Add environment variables
ALGOLIA_APP_ID=your_app_id
ALGOLIA_ADMIN_API_KEY=your_admin_api_key
ALGOLIA_INDEX_PREFIX=prod_ # optional
ALGOLIA_REINDEX_ON_BOOT=false # optionalHow it works
Lifecycle hooks (automatic sync)
| Event | Behaviour |
|---|---|
| afterCreate | Indexes the entry if it is published |
| afterUpdate | Indexes if published; removes from index if unpublished |
| afterDelete | Removes from index if it was published |
Algolia record shape
Every indexed entry produces:
{
"objectID": "api::article.article::abc123::en",
"title": "My Article",
"content": "Plain text extracted from all string/richtext/component fields",
"url": "/articles/my-article",
"domains": ["godrej-industries", "another-domain"]
}Admin panel — "Index all items"
A button appears in the content-manager list view for every collection type listed in contentTypes. Clicking it bulk-reindexes all published entries (paginated, 100 per batch).
contentTypes config reference
| Key | Type | Required | Description |
|---|---|---|---|
| uid | string | Yes | Strapi content type UID e.g. api::article.article |
| indexName | string | No | Algolia index name. Defaults to the schema's pluralName (collections) or singleTypeIndexName (single types) |
| titleField | string | No | Dot-notation path to the title field e.g. banner.title |
| staticTitle | string | No | Hard-coded title string (useful for single types) |
| urlPattern | string | No | Frontend URL with {slug} placeholder. Defaults to /{pluralName}/{slug} |
If both titleField and staticTitle are set, staticTitle takes precedence.
If neither is set, the plugin falls back to the first of title, name, heading fields found on the entry, then banner.title, then the schema's displayName.
Plugin services (for advanced use)
All services are accessible within custom Strapi code:
// Index a single entry manually
await strapi.plugin('algolia').service('algoliaSync').indexEntry(uid, documentId, locale);
// Remove a single entry
await strapi.plugin('algolia').service('algoliaSync').removeEntry(uid, documentId, locale);
// Reindex an entire collection
await strapi.plugin('algolia').service('algoliaSync').reindexCollectionUid(uid);
// Full reindex of all configured content types
await strapi.plugin('algolia').service('algoliaSync').fullReindex();Migrating from the inline integration (gil-corp-strapi)
If you are migrating this project away from the old inline utilities:
- Add the plugin config to
config/plugins.jsand copy the content type definitions from the oldsrc/utils/algolia-config.js. - Remove
src/utils/algolia.js,src/utils/algolia-sync.js,src/utils/algolia-config.js. - Remove the Algolia code from
src/index.js(lifecycle hooks + boot reindex). - Remove
src/api/algolia-admin/(controller + routes). - Remove the
AlgoliaIndexAllButtoninjection fromsrc/admin/app.js. - Set
resolveto the plugin folder path inconfig/plugins.js.
