Using Plugins
Plugins add pages and API routes to the admin. Install a package, register it in cms.config.ts, and grant access.
Installing a plugin
Three steps. Using the cache-revalidation plugin as the example:
1. Install the package
pnpm add @nextjscms/plugin-cache-revalidation2. Register it in cms.config.ts
import { cacheRevalidationPlugin } from '@nextjscms/plugin-cache-revalidation'
import { defineConfig } from 'nextjs-cms/core/config'
export default defineConfig({
plugins: [
// Short form: just the descriptor
cacheRevalidationPlugin,
],
})3. Register its page component
Plugin pages are rendered by the admin's catch-all plugin route. Map the plugin's name to its server entry:
export const pluginNamesMap: Record<string, string> = {
plugin_cache_revalidation: '@nextjscms/plugin-cache-revalidation/server',
// A workaround to avoid importing errors if no plugins are installed
blank: 'nextjs-cms/plugins/blank-component',
}The key is the plugin's name: its package name @nextjscms/plugin-<slug> becomes plugin_<slug_with_underscores>.
If the plugin ships styled components, make sure Tailwind scans it:
@source '../node_modules/@nextjscms/plugin-*/**/*.{tsx,ts,jsx,js}';Then grant admins access: each plugin appears in the privileges list on the Admins page (the Master admin gets it automatically).
Configuring a plugin
Use the long form to pass options, rename it, or change its icon:
plugins: [
{
plugin: cacheRevalidationPlugin,
options: {
contentTypes: ['posts', 'categories'],
skipInDevelopment: true,
},
override: {
title: { en: 'Site cache', ar: 'ذاكرة الموقع' },
icon: 'refresh-cw',
},
},
]| Key | Type | Description |
|---|---|---|
plugin | descriptor | The plugin, as exported by its package. |
options | Record<string, unknown> | Passed to the plugin's createPlugin(options). See each plugin's README. |
override.title | string | Record<locale, string> | Rename the sidebar entry. |
override.icon | Lucide icon name | Change the sidebar icon. |
override.routes | { [path]: { title?, icon? } } | Per-page overrides for plugins with several pages. Keys are type-checked against the plugin's routes. |
groupRoutes | boolean | For plugins with several pages: show them as a collapsible group (default true) or as separate sidebar items. |
How override applies:
| Plugin shape | groupRoutes | override.title / icon | override.routes[path] |
|---|---|---|---|
| One page | ignored | Renames the page | Renames the page (redundant) |
| Several pages | true (default) | Renames the sidebar group | Renames one page |
| Several pages | false | No effect (a warning is logged) | Renames one page |
Using a plugin page as the dashboard
Replace the default dashboard with any plugin page. It becomes visible to all signed-in admins, regardless of privileges:
dashboard: { override: '/cache-revalidation' },Official plugins
Cache revalidation
@nextjscms/plugin-cache-revalidation keeps a cached Next.js website in sync with the CMS. It sends a revalidation request to your site on every create, update, and delete, retries failures, records what never landed, and gives you a page to retry, dismiss, or purge.
import { siteRevalidationHooks } from '@nextjscms/plugin-cache-revalidation/hooks'
export default hasItemsSection({
// ...
hooks: siteRevalidationHooks('posts'), // cache tag used by your site
})| Option | Default | Description |
|---|---|---|
contentTypes | required | The cache tags your site uses. |
urlEnv | 'REVALIDATE_URL' | Env var with your site's origin. |
secretEnv | 'REVALIDATE_SECRET' | Env var with the shared secret. |
path | '/api/revalidate' | Revalidation route on your site. |
timeoutMs | 3000 | Per-attempt timeout. |
attempts | 2 | Attempts for retryable failures. |
skipInDevelopment | false | Send nothing unless NODE_ENV === 'production'. |
It also needs its dictionaries merged into i18n (see Plugin strings) and a revalidation route on your site. The package README has the full setup.
cPanel dashboard and cPanel emails
@nextjscms/plugin-cpanel-dashboard shows hosting information (disk, bandwidth, and so on) from cPanel. @nextjscms/plugin-cpanel-emails lists and manages the domain's email accounts. Both read these environment variables:
| Variable | Description |
|---|---|
CPANEL_DOMAIN | Your cPanel host. |
CPANEL_USER | cPanel username. |
CPANEL_API_TOKEN | API token (preferred). |
CPANEL_PASSWORD | Password, used only when no token is set. |
Google Analytics
@nextjscms/plugin-google-analytics reserves a Google Analytics page in the admin. It's an early preview.
Troubleshooting
| Symptom | Cause |
|---|---|
| The plugin isn't in the sidebar | The admin lacks the privilege, or the plugin isn't in cms.config.ts. |
| The page is blank | The plugin is missing from plugin-server-registry.ts. |
| The page is unstyled | Tailwind isn't scanning the plugin package (@source). |
Raw keys like revalidationTitle in the UI | The plugin's dictionaries aren't merged into i18n.supportedLanguages. |