Skip to Content
DocumentationBackendCreate new Site

Create new Site

Each site in the CMS5 multisite is a Strapi plugin under src/plugins/. This guide walks through scaffolding a new site plugin, registering it, wiring up the shared slug logic, and building it.

For this example we create a site called andronis.


1. Scaffold the plugin

Open a terminal in the cms5-backend root and run the command below. The argument is the path where the plugin is created, so pass the full src/plugins/<NAME> path (passing just <NAME> would create the plugin in the repo root instead):

npx @strapi/sdk-plugin@latest init src/plugins/<NAME>

Important: answer no to register with the admin panel? and yes to register with the server?. Answering no to the admin panel keeps the plugin server-only (no admin/ folder is generated).

You will be prompted for the following, in order (the plugin id must match /^[a-z0-9][a-z0-9-_]*$/):

? plugin name › andronis ? plugin id (used by Strapi) › andronis ? plugin display name › Andronis ? plugin description › Andronis CMS5 ? plugin author name › John Paraskevopoulos ? plugin author email › jparaskevopoulos@nelios.com ? git url › ? plugin license › MIT ? register with the admin panel? › no ? register with the server? › yes ? Add .editorconfig? › yes ? Use ESLint? › yes ? Use Prettier? › yes ? Use TypeScript? › yes

2. Fix the plugin’s dependencies

Once the script finishes it will attempt to install node modules — it might crash, ignore it. Open the package.json of your new plugin (src/plugins/andronis/package.json) and replace the dependencies, devDependencies, and peerDependencies with the ones any other site uses:

{ "dependencies":{ "@strapi/types":"5.48.0" }, "devDependencies":{ "@strapi/sdk-plugin":"^5.3.2", "@strapi/typescript-utils":"^5.12.6", "prettier":"^3.5.3", "typescript":"^5.8.3" }, "peerDependencies":{ "@strapi/sdk-plugin":"^5.3.2", "@strapi/strapi":"^5.35.0" } }

Note: These versions drift over time — always copy from the package.json of an existing site plugin (e.g. src/plugins/andronis) rather than trusting the snippet above.


3. Register the plugin

Add the plugin to config/plugins.ts:

export default { // …other plugins 'andronis': { enabled: true, resolve: './src/plugins/andronis' }, // …other plugins }

Note: The key name (andronis) must match the plugin name you used when scaffolding.


4. Generate the lifecycle hooks

Run the helper script and enter the same name you used above:

pnpm run add:plugin
Enter plugin name (e.g., my-plugin): andronis ✅ register.ts has been overwritten in order to enable lifecycle hooks: src/plugins/andronis/server/src/register.ts ✅ Copied lib folder from 'demo' to src/plugins/andronis/lib ℹ️ 'andronis' lives under src/plugins/* and will be built automatically by 'pnpm run buildAll'.

This does everything needed to wire up the site’s slug logic:

  • Overwrites the plugin’s server/src/register.ts with beforeCreate / beforeUpdate lifecycle hooks that auto-generate the Slug field for any content type that has one, importing the shared helper from ../../lib/NeliosSlug.
  • Copies the shared lib folder (NeliosSlug.ts + helpers.ts) from an existing plugin into src/plugins/<name>/lib/, so that import resolves when the plugin is built in isolation.

Notes

  • The plugin name is validated — only letters, numbers, dashes, and underscores are allowed; anything else is rejected.
  • No build:plugins edit is needed. Because src/plugins/* is a pnpm workspace, the new plugin is picked up automatically by build:plugins (pnpm -r --if-present build).
  • If the plugin already has a lib folder it is left untouched; if no donor plugin is found, the script warns you to copy a lib folder in manually.

5. Build

To apply changes, from the plugin directory src/plugins/<name>/ run:

pnpm run build

or, during development:

pnpm run watch

To build everything (shared packages, types, all plugins, then Strapi) run from the cms5-backend root:

pnpm run buildAll

Review the changes locally before deploying.

Last updated on