From 00086965e7109dfac8f01f38fc05e24ccf9863ad Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:09:48 +0000 Subject: [PATCH 01/17] docs(backend): correct TypeScript code fences in TS tabs (controllers, services, middlewares, routes) --- docusaurus/docs/cms/backend-customization/controllers.md | 2 +- docusaurus/docs/cms/backend-customization/middlewares.md | 2 +- docusaurus/docs/cms/backend-customization/routes.md | 4 ++-- docusaurus/docs/cms/backend-customization/services.md | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docusaurus/docs/cms/backend-customization/controllers.md b/docusaurus/docs/cms/backend-customization/controllers.md index 75dc481553..67d0b72ca2 100644 --- a/docusaurus/docs/cms/backend-customization/controllers.md +++ b/docusaurus/docs/cms/backend-customization/controllers.md @@ -95,7 +95,7 @@ module.exports = createCoreController('api::restaurant.restaurant', ({ strapi }) -```js title="./src/api/restaurant/controllers/restaurant.ts" +```ts title="./src/api/restaurant/controllers/restaurant.ts" import { factories } from '@strapi/strapi'; diff --git a/docusaurus/docs/cms/backend-customization/middlewares.md b/docusaurus/docs/cms/backend-customization/middlewares.md index 57e930bdbd..f47ee9f6e7 100644 --- a/docusaurus/docs/cms/backend-customization/middlewares.md +++ b/docusaurus/docs/cms/backend-customization/middlewares.md @@ -108,7 +108,7 @@ module.exports = () => { -```js title="/config/middlewares.ts" +```ts title="/config/middlewares.ts" export default () => { return async (ctx, next) => { diff --git a/docusaurus/docs/cms/backend-customization/routes.md b/docusaurus/docs/cms/backend-customization/routes.md index ef5747a454..54a5ce2d46 100644 --- a/docusaurus/docs/cms/backend-customization/routes.md +++ b/docusaurus/docs/cms/backend-customization/routes.md @@ -97,7 +97,7 @@ module.exports = createCoreRouter('api::restaurant.restaurant', { -```js title="./src/api/[apiName]/routes/[routerName].ts (e.g './src/api/restaurant/routes/restaurant.ts')" +```ts title="./src/api/[apiName]/routes/[routerName].ts (e.g './src/api/restaurant/routes/restaurant.ts')" import { factories } from '@strapi/strapi'; @@ -149,7 +149,7 @@ module.exports = createCoreRouter('api::restaurant.restaurant', { -```js title="./src/api/restaurant/routes/restaurant.ts" +```ts title="./src/api/restaurant/routes/restaurant.ts" import { factories } from '@strapi/strapi'; diff --git a/docusaurus/docs/cms/backend-customization/services.md b/docusaurus/docs/cms/backend-customization/services.md index 86c5e7442d..ff0c26cc3b 100644 --- a/docusaurus/docs/cms/backend-customization/services.md +++ b/docusaurus/docs/cms/backend-customization/services.md @@ -83,7 +83,7 @@ module.exports = createCoreService('api::restaurant.restaurant', ({ strapi }) => -```js title="./src/api/restaurant/services/restaurant.ts" +```ts title="./src/api/restaurant/services/restaurant.ts" import { factories } from '@strapi/strapi'; @@ -171,7 +171,7 @@ module.exports = createCoreService('api::restaurant.restaurant', ({ strapi }) => -```js title="./src/api/restaurant/services/restaurant.ts" +```ts title="./src/api/restaurant/services/restaurant.ts" import { factories } from '@strapi/strapi'; From 49a15fb84c95c9166c39a7c5d79725c485df8f55 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:09:54 +0000 Subject: [PATCH 02/17] docs(bundlers): clarify webpack config example rename and JS/TS filenames --- .../docs/cms/admin-panel-customization/bundlers.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/docusaurus/docs/cms/admin-panel-customization/bundlers.md b/docusaurus/docs/cms/admin-panel-customization/bundlers.md index 81b485a2db..25ebf19dc1 100644 --- a/docusaurus/docs/cms/admin-panel-customization/bundlers.md +++ b/docusaurus/docs/cms/admin-panel-customization/bundlers.md @@ -80,10 +80,15 @@ strapi develop --bundler=webpack ``` :::prerequisites -Make sure to rename the default `webpack.config.example.js` file into `webpack.config.` before customizing webpack. +If you plan to customize webpack, start from the example file in your project root. Rename: + +- `webpack.config.example.js` → `webpack.config.js` (JavaScript) +- or `webpack.config.example.ts` → `webpack.config.ts` (TypeScript) + +Strapi will pick up `webpack.config.js` or `webpack.config.ts` automatically when you run `strapi develop --bundler=webpack`. ::: -In order to extend the usage of webpack v5, define a function that extends its configuration inside `/src/admin/webpack.config.`: +To extend webpack v5, define a function that returns a modified config in `/src/admin/webpack.config.js` or `/src/admin/webpack.config.ts`: @@ -118,4 +123,3 @@ export default (config, webpack) => { - From 9502ba1c65eca433a9d6c53277dd9ba2a4d93e03 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:10:01 +0000 Subject: [PATCH 03/17] docs(routes): add guidance to prefer fully-qualified handler names in custom routers --- docusaurus/docs/cms/backend-customization/routes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docusaurus/docs/cms/backend-customization/routes.md b/docusaurus/docs/cms/backend-customization/routes.md index 54a5ce2d46..f5920ea584 100644 --- a/docusaurus/docs/cms/backend-customization/routes.md +++ b/docusaurus/docs/cms/backend-customization/routes.md @@ -168,7 +168,7 @@ export default factories.createCoreRouter('api::restaurant.restaurant', { -This only allows a `GET` request on the `/restaurants` path from the core `find` [controller](/cms/backend-customization/controllers) without authentication. +This only allows a `GET` request on the `/restaurants` path from the core `find` [controller](/cms/backend-customization/controllers) without authentication. When you reference custom controller actions in custom routers, prefer the fully‑qualified `api::..` form for clarity (e.g., `api::restaurant.restaurant.review`). ### Creating custom routers From 8ad2c1fe6c05f370596a10122889ab4d01cc5b65 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:10:17 +0000 Subject: [PATCH 04/17] docs(api-tokens): add concise security tip (least privilege, rotation, secrets manager) --- docusaurus/docs/cms/features/api-tokens.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docusaurus/docs/cms/features/api-tokens.md b/docusaurus/docs/cms/features/api-tokens.md index 7f63b377c9..08ff86b2d7 100644 --- a/docusaurus/docs/cms/features/api-tokens.md +++ b/docusaurus/docs/cms/features/api-tokens.md @@ -19,6 +19,10 @@ API tokens provide scoped authentication for REST and GraphQL requests without e API tokens allow users to authenticate REST and GraphQL API queries (see [APIs introduction](/cms/api/content-api)). +:::tip Security +Prefer read‑only tokens for public access, scope server tokens to only what you need, rotate long‑lived tokens, and store them in a secrets manager. Never expose admin tokens in client‑side code. +::: + Free feature From aff6accbb9153c28aad5b85b867515f40dac4687 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:11:05 +0000 Subject: [PATCH 05/17] docs(controllers): add caution about validateQuery/sanitizeQuery/sanitizeOutput when overriding actions --- docusaurus/docs/cms/backend-customization/controllers.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docusaurus/docs/cms/backend-customization/controllers.md b/docusaurus/docs/cms/backend-customization/controllers.md index 67d0b72ca2..0cc69e6cf4 100644 --- a/docusaurus/docs/cms/backend-customization/controllers.md +++ b/docusaurus/docs/cms/backend-customization/controllers.md @@ -29,6 +29,10 @@ In most cases, the controllers will contain the bulk of a project's business log
The diagram represents a simplified version of how a request travels through the Strapi back end, with controllers highlighted. The backend customization introduction page includes a complete, interactive diagram.
+:::caution Sanitize inputs and outputs +When overriding core actions, always validate and sanitize queries and responses to avoid leaking private fields or bypassing access rules. Use `validateQuery` (optional), `sanitizeQuery` (recommended), and `sanitizeOutput` before returning data from custom actions. See the example below for a safe `find` override. +::: + ## Implementation Controllers can be [generated or added manually](#adding-a-new-controller). Strapi provides a `createCoreController` factory function that automatically generates core controllers and allows building custom ones or [extend or replace the generated controllers](#extending-core-controllers). From afa94175752aab4cf57eae7a8b9f7713b898d824 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:11:24 +0000 Subject: [PATCH 06/17] docs(policies): clarify scoped policy folders and fix example path --- docusaurus/docs/cms/backend-customization/policies.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/backend-customization/policies.md b/docusaurus/docs/cms/backend-customization/policies.md index 251ec3902d..6a1adf2451 100644 --- a/docusaurus/docs/cms/backend-customization/policies.md +++ b/docusaurus/docs/cms/backend-customization/policies.md @@ -24,7 +24,7 @@ Policies are functions that execute specific logic on each request before it rea Each [route](/cms/backend-customization/routes) of a Strapi project can be associated to an array of policies. For example, a policy named `is-admin` could check that the request is sent by an admin user, and restrict access to critical routes. -Policies can be global or scoped. [Global policies](#global-policies) can be associated to any route in the project. Scoped policies only apply to a specific [API](#api-policies) or [plugin](#plugin-policies). +Policies can be global or scoped. [Global policies](#global-policies) can be associated to any route in the project. Scoped policies only apply to a specific [API](#api-policies) or [plugin](#plugin-policies) and should live under the corresponding `./src/api//policies/` or `./src/plugins//policies/` folder.
Simplified Strapi backend diagram with routes and policies highlighted @@ -89,7 +89,7 @@ Policies can be configured using a `config` object: -```js title=".src/api/[api-name]/policies/my-policy.js" +```js title="./src/api/[api-name]/policies/my-policy.js" module.exports = (policyContext, config, { strapi }) => { if (policyContext.state.user.role.code === config.role) { // if user's role is the same as the one described in configuration From 1badc7393efe2efc3ea14e8ef0ba6d0672f8ee3b Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:11:31 +0000 Subject: [PATCH 07/17] docs(webhooks): add signature verification tip and fix TS config path --- docusaurus/docs/cms/backend-customization/webhooks.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docusaurus/docs/cms/backend-customization/webhooks.md b/docusaurus/docs/cms/backend-customization/webhooks.md index c40e959340..410c0e233b 100644 --- a/docusaurus/docs/cms/backend-customization/webhooks.md +++ b/docusaurus/docs/cms/backend-customization/webhooks.md @@ -73,6 +73,7 @@ export default { Most of the time, webhooks make requests to public URLs, therefore it is possible that someone may find that URL and send it wrong information. To prevent this from happening you can send a header with an authentication token. Using the Admin panel you would have to do it for every webhook. +Consider signing webhook payloads and verifying signatures server‑side to prevent replay attacks. Another way is to define `defaultHeaders` to add to every webhook request. You can configure these global headers by updating the file at `./config/server`: @@ -98,7 +99,7 @@ module.exports = { -```js title="./config.server.ts" +```js title="./config/server.ts" export default { webhooks: { defaultHeaders: { @@ -514,4 +515,4 @@ The event is triggered when a [release](/cms/features/releases) is published. :::tip If you want to learn more about how to use webhooks with Next.js, please have a look at the [dedicated blog article](https://strapi.io/blog/how-to-create-an-ssg-static-site-generation-application-with-strapi-webhooks-and-nextjs). -::: \ No newline at end of file +::: From 8406c4f159b685aaf9eaa1f3f4ed19c4d0058f41 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:11:37 +0000 Subject: [PATCH 08/17] docs(theme-extension): add minimal TS example for theme.light and theme.dark overrides --- .../theme-extension.md | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/docusaurus/docs/cms/admin-panel-customization/theme-extension.md b/docusaurus/docs/cms/admin-panel-customization/theme-extension.md index 67593b76c0..d6ca1648b0 100644 --- a/docusaurus/docs/cms/admin-panel-customization/theme-extension.md +++ b/docusaurus/docs/cms/admin-panel-customization/theme-extension.md @@ -21,3 +21,25 @@ To extend the theme, use either: :::strapi Strapi Design System The default defines various theme-related keys (shadows, colors…) that can be updated through the `config.theme.light` and `config.theme.dark` keys in `./admin/src/app.js`. The is fully customizable and has a dedicated documentation. ::: + +### Example (TypeScript) + +```ts title="/src/admin/app.ts" +export default { + config: { + theme: { + light: { + colors: { + primary600: '#4A6EFF', + }, + }, + dark: { + colors: { + primary600: '#9DB2FF', + }, + }, + }, + }, + bootstrap() {}, +} +``` From 9162e3e38ebd1d324b5fd764a57826b592555d69 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:11:44 +0000 Subject: [PATCH 09/17] docs(wysiwyg): add next steps tip (plugin first, custom field for deeper integration) --- .../docs/cms/admin-panel-customization/wysiwyg-editor.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docusaurus/docs/cms/admin-panel-customization/wysiwyg-editor.md b/docusaurus/docs/cms/admin-panel-customization/wysiwyg-editor.md index e427877b4b..b9fe3a77e6 100644 --- a/docusaurus/docs/cms/admin-panel-customization/wysiwyg-editor.md +++ b/docusaurus/docs/cms/admin-panel-customization/wysiwyg-editor.md @@ -15,3 +15,7 @@ Strapi's [admin panel](/cms/admin-panel-customization) comes with a built-in ric - You can install a third-party plugin, such as one for CKEditor, by visiting . - You can create your own plugin to create and register a fully custom WYSIWYG field (see [custom fields documentation](/cms/features/custom-fields)). + +:::tip Next steps +When evaluating editors, start with a plugin from the Marketplace for a quick trial, then consider a custom field if you need deeper integration (schema, validation, or custom toolbar behavior). +::: From 5e2084803527d2bea7ebd75393f72a2c6484a292 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:11:51 +0000 Subject: [PATCH 10/17] docs(middlewares): add tip to list registered middlewares (discovery command) --- docusaurus/docs/cms/backend-customization/middlewares.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docusaurus/docs/cms/backend-customization/middlewares.md b/docusaurus/docs/cms/backend-customization/middlewares.md index f47ee9f6e7..1f000f862b 100644 --- a/docusaurus/docs/cms/backend-customization/middlewares.md +++ b/docusaurus/docs/cms/backend-customization/middlewares.md @@ -129,6 +129,10 @@ export default () => { The GraphQL plugin also allows [implementing custom middlewares](/cms/plugins/graphql#middlewares), with a different syntax. +:::tip Discover loaded middlewares +Run `yarn strapi middlewares:list` to list all registered middlewares and double‑check naming when wiring them in routers. +::: + ## Usage Middlewares are called different ways depending on their scope: From 7b79f9bf8b62db0b3deb76d7c023cc86cf27e841 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:11:58 +0000 Subject: [PATCH 11/17] docs(models): add TL;DR with emphasis on content shape and Document Service --- docusaurus/docs/cms/backend-customization/models.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docusaurus/docs/cms/backend-customization/models.md b/docusaurus/docs/cms/backend-customization/models.md index a89ce419ac..ccc2b4842a 100644 --- a/docusaurus/docs/cms/backend-customization/models.md +++ b/docusaurus/docs/cms/backend-customization/models.md @@ -16,6 +16,10 @@ tags: # Models + +Models define your content types’ shape and drive generated controllers and routes. Use the Document Service API to query/create/update data and keep controllers thin. + + Models define Strapi’s content structure via content-types and reusable components. This documentation walks through creating these models in the Content-type Builder or CLI and managing schema files with optional lifecycle hooks. From 4fc26e0599a6925f0b407e9d4fb60b79354541f9 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:25:48 +0000 Subject: [PATCH 12/17] docs(locales-translations): fix typo and use proper js/ts fences instead of jsx --- .../admin-panel-customization/locales-translations.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/docusaurus/docs/cms/admin-panel-customization/locales-translations.md b/docusaurus/docs/cms/admin-panel-customization/locales-translations.md index f8c7df02a8..2eea43effa 100644 --- a/docusaurus/docs/cms/admin-panel-customization/locales-translations.md +++ b/docusaurus/docs/cms/admin-panel-customization/locales-translations.md @@ -17,7 +17,7 @@ Configure the admin panel languages by updating the `config.locales` array and o The Strapi [admin panel](/cms/admin-panel-customization) ships with English strings and supports adding other locales so your editorial team can work in their preferred language. Locales determine which languages appear in the interface, while translations provide the text displayed for each key in a locale. -This guide targets project maintainers customizing the admin experience from the application codebase. All examples modify the configuration exported from `/src/admin/app`file, which Strapi loads when the admin panel builds. You'll learn how to declare additional locales and how to extend Strapi or plugin translations when a locale is missing strings. +This guide targets project maintainers customizing the admin experience from the application codebase. All examples modify the configuration exported from `/src/admin/app` file, which Strapi loads when the admin panel builds. You'll learn how to declare additional locales and how to extend Strapi or plugin translations when a locale is missing strings. ## Defining locales @@ -26,7 +26,7 @@ To update the list of available locales in the admin panel, set the `config.loca -```jsx title="/src/admin/app.js" +```js title="/src/admin/app.js" export default { config: { locales: ["ru", "zh"], @@ -39,7 +39,7 @@ export default { -```jsx title="/src/admin/app.ts" +```ts title="/src/admin/app.ts" export default { config: { locales: ["ru", "zh"], @@ -89,7 +89,7 @@ export default { -```js title="/src/admin/app.ts" +```ts title="/src/admin/app.ts" export default { config: { locales: ["fr"], @@ -136,7 +136,7 @@ export default { -```js title="/src/admin/app.ts" +```ts title="/src/admin/app.ts" export default { config: { locales: ["fr"], From 2d1e93fe5e418d5bc0c197c5c5b47c33e9b6f2f3 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 12:25:50 +0000 Subject: [PATCH 13/17] docs(logos): add TL;DR and guidance (SVG preferred, light/dark variants) --- docusaurus/docs/cms/admin-panel-customization/logos.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docusaurus/docs/cms/admin-panel-customization/logos.md b/docusaurus/docs/cms/admin-panel-customization/logos.md index bfa87d0446..f96621be45 100644 --- a/docusaurus/docs/cms/admin-panel-customization/logos.md +++ b/docusaurus/docs/cms/admin-panel-customization/logos.md @@ -11,6 +11,10 @@ tags: # Logos + +Update login and navigation logos by extending the admin app. Prefer SVG for crisp rendering; provide light/dark variants when possible for contrast. + + Strapi's [admin panel](/cms/admin-panel-customization) displays its branding on both the login screen and in the main navigation. Replacing these images allows you to match the interface to your identity. The present page shows how to override the two logo files via the admin panel configuration. If you prefer uploading them directly in the UI, see [Customizing the logo](/cms/features/admin-panel#customizing-the-logo). The Strapi admin panel displays a logo in 2 different locations, represented by 2 different keys in the admin panel configuration: From 01301f6ea32a60d4ace1622450196eae4e5fdc9a Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 16:31:16 +0000 Subject: [PATCH 14/17] Limit PR scope based on title; keep only intended doc(s); revert unrelated files --- .../cms/admin-panel-customization/bundlers.md | 10 +++------ .../locales-translations.md | 10 ++++----- .../cms/admin-panel-customization/logos.md | 4 ---- .../theme-extension.md | 22 ------------------- .../wysiwyg-editor.md | 4 ---- .../cms/backend-customization/controllers.md | 6 +---- .../cms/backend-customization/middlewares.md | 6 +---- .../docs/cms/backend-customization/models.md | 4 ---- .../cms/backend-customization/policies.md | 4 ++-- .../docs/cms/backend-customization/routes.md | 6 ++--- .../cms/backend-customization/services.md | 4 ++-- .../cms/backend-customization/webhooks.md | 5 ++--- docusaurus/docs/cms/features/api-tokens.md | 4 ---- 13 files changed, 19 insertions(+), 70 deletions(-) diff --git a/docusaurus/docs/cms/admin-panel-customization/bundlers.md b/docusaurus/docs/cms/admin-panel-customization/bundlers.md index 25ebf19dc1..81b485a2db 100644 --- a/docusaurus/docs/cms/admin-panel-customization/bundlers.md +++ b/docusaurus/docs/cms/admin-panel-customization/bundlers.md @@ -80,15 +80,10 @@ strapi develop --bundler=webpack ``` :::prerequisites -If you plan to customize webpack, start from the example file in your project root. Rename: - -- `webpack.config.example.js` → `webpack.config.js` (JavaScript) -- or `webpack.config.example.ts` → `webpack.config.ts` (TypeScript) - -Strapi will pick up `webpack.config.js` or `webpack.config.ts` automatically when you run `strapi develop --bundler=webpack`. +Make sure to rename the default `webpack.config.example.js` file into `webpack.config.` before customizing webpack. ::: -To extend webpack v5, define a function that returns a modified config in `/src/admin/webpack.config.js` or `/src/admin/webpack.config.ts`: +In order to extend the usage of webpack v5, define a function that extends its configuration inside `/src/admin/webpack.config.`: @@ -123,3 +118,4 @@ export default (config, webpack) => { + diff --git a/docusaurus/docs/cms/admin-panel-customization/locales-translations.md b/docusaurus/docs/cms/admin-panel-customization/locales-translations.md index 2eea43effa..f8c7df02a8 100644 --- a/docusaurus/docs/cms/admin-panel-customization/locales-translations.md +++ b/docusaurus/docs/cms/admin-panel-customization/locales-translations.md @@ -17,7 +17,7 @@ Configure the admin panel languages by updating the `config.locales` array and o The Strapi [admin panel](/cms/admin-panel-customization) ships with English strings and supports adding other locales so your editorial team can work in their preferred language. Locales determine which languages appear in the interface, while translations provide the text displayed for each key in a locale. -This guide targets project maintainers customizing the admin experience from the application codebase. All examples modify the configuration exported from `/src/admin/app` file, which Strapi loads when the admin panel builds. You'll learn how to declare additional locales and how to extend Strapi or plugin translations when a locale is missing strings. +This guide targets project maintainers customizing the admin experience from the application codebase. All examples modify the configuration exported from `/src/admin/app`file, which Strapi loads when the admin panel builds. You'll learn how to declare additional locales and how to extend Strapi or plugin translations when a locale is missing strings. ## Defining locales @@ -26,7 +26,7 @@ To update the list of available locales in the admin panel, set the `config.loca -```js title="/src/admin/app.js" +```jsx title="/src/admin/app.js" export default { config: { locales: ["ru", "zh"], @@ -39,7 +39,7 @@ export default { -```ts title="/src/admin/app.ts" +```jsx title="/src/admin/app.ts" export default { config: { locales: ["ru", "zh"], @@ -89,7 +89,7 @@ export default { -```ts title="/src/admin/app.ts" +```js title="/src/admin/app.ts" export default { config: { locales: ["fr"], @@ -136,7 +136,7 @@ export default { -```ts title="/src/admin/app.ts" +```js title="/src/admin/app.ts" export default { config: { locales: ["fr"], diff --git a/docusaurus/docs/cms/admin-panel-customization/logos.md b/docusaurus/docs/cms/admin-panel-customization/logos.md index f96621be45..bfa87d0446 100644 --- a/docusaurus/docs/cms/admin-panel-customization/logos.md +++ b/docusaurus/docs/cms/admin-panel-customization/logos.md @@ -11,10 +11,6 @@ tags: # Logos - -Update login and navigation logos by extending the admin app. Prefer SVG for crisp rendering; provide light/dark variants when possible for contrast. - - Strapi's [admin panel](/cms/admin-panel-customization) displays its branding on both the login screen and in the main navigation. Replacing these images allows you to match the interface to your identity. The present page shows how to override the two logo files via the admin panel configuration. If you prefer uploading them directly in the UI, see [Customizing the logo](/cms/features/admin-panel#customizing-the-logo). The Strapi admin panel displays a logo in 2 different locations, represented by 2 different keys in the admin panel configuration: diff --git a/docusaurus/docs/cms/admin-panel-customization/theme-extension.md b/docusaurus/docs/cms/admin-panel-customization/theme-extension.md index d6ca1648b0..67593b76c0 100644 --- a/docusaurus/docs/cms/admin-panel-customization/theme-extension.md +++ b/docusaurus/docs/cms/admin-panel-customization/theme-extension.md @@ -21,25 +21,3 @@ To extend the theme, use either: :::strapi Strapi Design System The default defines various theme-related keys (shadows, colors…) that can be updated through the `config.theme.light` and `config.theme.dark` keys in `./admin/src/app.js`. The is fully customizable and has a dedicated documentation. ::: - -### Example (TypeScript) - -```ts title="/src/admin/app.ts" -export default { - config: { - theme: { - light: { - colors: { - primary600: '#4A6EFF', - }, - }, - dark: { - colors: { - primary600: '#9DB2FF', - }, - }, - }, - }, - bootstrap() {}, -} -``` diff --git a/docusaurus/docs/cms/admin-panel-customization/wysiwyg-editor.md b/docusaurus/docs/cms/admin-panel-customization/wysiwyg-editor.md index b9fe3a77e6..e427877b4b 100644 --- a/docusaurus/docs/cms/admin-panel-customization/wysiwyg-editor.md +++ b/docusaurus/docs/cms/admin-panel-customization/wysiwyg-editor.md @@ -15,7 +15,3 @@ Strapi's [admin panel](/cms/admin-panel-customization) comes with a built-in ric - You can install a third-party plugin, such as one for CKEditor, by visiting . - You can create your own plugin to create and register a fully custom WYSIWYG field (see [custom fields documentation](/cms/features/custom-fields)). - -:::tip Next steps -When evaluating editors, start with a plugin from the Marketplace for a quick trial, then consider a custom field if you need deeper integration (schema, validation, or custom toolbar behavior). -::: diff --git a/docusaurus/docs/cms/backend-customization/controllers.md b/docusaurus/docs/cms/backend-customization/controllers.md index 0cc69e6cf4..75dc481553 100644 --- a/docusaurus/docs/cms/backend-customization/controllers.md +++ b/docusaurus/docs/cms/backend-customization/controllers.md @@ -29,10 +29,6 @@ In most cases, the controllers will contain the bulk of a project's business log
The diagram represents a simplified version of how a request travels through the Strapi back end, with controllers highlighted. The backend customization introduction page includes a complete, interactive diagram.
-:::caution Sanitize inputs and outputs -When overriding core actions, always validate and sanitize queries and responses to avoid leaking private fields or bypassing access rules. Use `validateQuery` (optional), `sanitizeQuery` (recommended), and `sanitizeOutput` before returning data from custom actions. See the example below for a safe `find` override. -::: - ## Implementation Controllers can be [generated or added manually](#adding-a-new-controller). Strapi provides a `createCoreController` factory function that automatically generates core controllers and allows building custom ones or [extend or replace the generated controllers](#extending-core-controllers). @@ -99,7 +95,7 @@ module.exports = createCoreController('api::restaurant.restaurant', ({ strapi }) -```ts title="./src/api/restaurant/controllers/restaurant.ts" +```js title="./src/api/restaurant/controllers/restaurant.ts" import { factories } from '@strapi/strapi'; diff --git a/docusaurus/docs/cms/backend-customization/middlewares.md b/docusaurus/docs/cms/backend-customization/middlewares.md index 1f000f862b..57e930bdbd 100644 --- a/docusaurus/docs/cms/backend-customization/middlewares.md +++ b/docusaurus/docs/cms/backend-customization/middlewares.md @@ -108,7 +108,7 @@ module.exports = () => { -```ts title="/config/middlewares.ts" +```js title="/config/middlewares.ts" export default () => { return async (ctx, next) => { @@ -129,10 +129,6 @@ export default () => { The GraphQL plugin also allows [implementing custom middlewares](/cms/plugins/graphql#middlewares), with a different syntax. -:::tip Discover loaded middlewares -Run `yarn strapi middlewares:list` to list all registered middlewares and double‑check naming when wiring them in routers. -::: - ## Usage Middlewares are called different ways depending on their scope: diff --git a/docusaurus/docs/cms/backend-customization/models.md b/docusaurus/docs/cms/backend-customization/models.md index ccc2b4842a..a89ce419ac 100644 --- a/docusaurus/docs/cms/backend-customization/models.md +++ b/docusaurus/docs/cms/backend-customization/models.md @@ -16,10 +16,6 @@ tags: # Models - -Models define your content types’ shape and drive generated controllers and routes. Use the Document Service API to query/create/update data and keep controllers thin. - - Models define Strapi’s content structure via content-types and reusable components. This documentation walks through creating these models in the Content-type Builder or CLI and managing schema files with optional lifecycle hooks. diff --git a/docusaurus/docs/cms/backend-customization/policies.md b/docusaurus/docs/cms/backend-customization/policies.md index 6a1adf2451..251ec3902d 100644 --- a/docusaurus/docs/cms/backend-customization/policies.md +++ b/docusaurus/docs/cms/backend-customization/policies.md @@ -24,7 +24,7 @@ Policies are functions that execute specific logic on each request before it rea Each [route](/cms/backend-customization/routes) of a Strapi project can be associated to an array of policies. For example, a policy named `is-admin` could check that the request is sent by an admin user, and restrict access to critical routes. -Policies can be global or scoped. [Global policies](#global-policies) can be associated to any route in the project. Scoped policies only apply to a specific [API](#api-policies) or [plugin](#plugin-policies) and should live under the corresponding `./src/api//policies/` or `./src/plugins//policies/` folder. +Policies can be global or scoped. [Global policies](#global-policies) can be associated to any route in the project. Scoped policies only apply to a specific [API](#api-policies) or [plugin](#plugin-policies).
Simplified Strapi backend diagram with routes and policies highlighted @@ -89,7 +89,7 @@ Policies can be configured using a `config` object: -```js title="./src/api/[api-name]/policies/my-policy.js" +```js title=".src/api/[api-name]/policies/my-policy.js" module.exports = (policyContext, config, { strapi }) => { if (policyContext.state.user.role.code === config.role) { // if user's role is the same as the one described in configuration diff --git a/docusaurus/docs/cms/backend-customization/routes.md b/docusaurus/docs/cms/backend-customization/routes.md index f5920ea584..ef5747a454 100644 --- a/docusaurus/docs/cms/backend-customization/routes.md +++ b/docusaurus/docs/cms/backend-customization/routes.md @@ -97,7 +97,7 @@ module.exports = createCoreRouter('api::restaurant.restaurant', { -```ts title="./src/api/[apiName]/routes/[routerName].ts (e.g './src/api/restaurant/routes/restaurant.ts')" +```js title="./src/api/[apiName]/routes/[routerName].ts (e.g './src/api/restaurant/routes/restaurant.ts')" import { factories } from '@strapi/strapi'; @@ -149,7 +149,7 @@ module.exports = createCoreRouter('api::restaurant.restaurant', { -```ts title="./src/api/restaurant/routes/restaurant.ts" +```js title="./src/api/restaurant/routes/restaurant.ts" import { factories } from '@strapi/strapi'; @@ -168,7 +168,7 @@ export default factories.createCoreRouter('api::restaurant.restaurant', { -This only allows a `GET` request on the `/restaurants` path from the core `find` [controller](/cms/backend-customization/controllers) without authentication. When you reference custom controller actions in custom routers, prefer the fully‑qualified `api::..` form for clarity (e.g., `api::restaurant.restaurant.review`). +This only allows a `GET` request on the `/restaurants` path from the core `find` [controller](/cms/backend-customization/controllers) without authentication. ### Creating custom routers diff --git a/docusaurus/docs/cms/backend-customization/services.md b/docusaurus/docs/cms/backend-customization/services.md index ff0c26cc3b..86c5e7442d 100644 --- a/docusaurus/docs/cms/backend-customization/services.md +++ b/docusaurus/docs/cms/backend-customization/services.md @@ -83,7 +83,7 @@ module.exports = createCoreService('api::restaurant.restaurant', ({ strapi }) => -```ts title="./src/api/restaurant/services/restaurant.ts" +```js title="./src/api/restaurant/services/restaurant.ts" import { factories } from '@strapi/strapi'; @@ -171,7 +171,7 @@ module.exports = createCoreService('api::restaurant.restaurant', ({ strapi }) => -```ts title="./src/api/restaurant/services/restaurant.ts" +```js title="./src/api/restaurant/services/restaurant.ts" import { factories } from '@strapi/strapi'; diff --git a/docusaurus/docs/cms/backend-customization/webhooks.md b/docusaurus/docs/cms/backend-customization/webhooks.md index 410c0e233b..c40e959340 100644 --- a/docusaurus/docs/cms/backend-customization/webhooks.md +++ b/docusaurus/docs/cms/backend-customization/webhooks.md @@ -73,7 +73,6 @@ export default { Most of the time, webhooks make requests to public URLs, therefore it is possible that someone may find that URL and send it wrong information. To prevent this from happening you can send a header with an authentication token. Using the Admin panel you would have to do it for every webhook. -Consider signing webhook payloads and verifying signatures server‑side to prevent replay attacks. Another way is to define `defaultHeaders` to add to every webhook request. You can configure these global headers by updating the file at `./config/server`: @@ -99,7 +98,7 @@ module.exports = { -```js title="./config/server.ts" +```js title="./config.server.ts" export default { webhooks: { defaultHeaders: { @@ -515,4 +514,4 @@ The event is triggered when a [release](/cms/features/releases) is published. :::tip If you want to learn more about how to use webhooks with Next.js, please have a look at the [dedicated blog article](https://strapi.io/blog/how-to-create-an-ssg-static-site-generation-application-with-strapi-webhooks-and-nextjs). -::: +::: \ No newline at end of file diff --git a/docusaurus/docs/cms/features/api-tokens.md b/docusaurus/docs/cms/features/api-tokens.md index 08ff86b2d7..7f63b377c9 100644 --- a/docusaurus/docs/cms/features/api-tokens.md +++ b/docusaurus/docs/cms/features/api-tokens.md @@ -19,10 +19,6 @@ API tokens provide scoped authentication for REST and GraphQL requests without e API tokens allow users to authenticate REST and GraphQL API queries (see [APIs introduction](/cms/api/content-api)). -:::tip Security -Prefer read‑only tokens for public access, scope server tokens to only what you need, rotate long‑lived tokens, and store them in a secrets manager. Never expose admin tokens in client‑side code. -::: - Free feature From c9d7eee9db46db9f2c6f65993f08fa40cbac1603 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 20:47:53 +0000 Subject: [PATCH 15/17] Email docs: add TypeScript provider config alongside JS via Tabs; add deliverability tip (SPF/DKIM, defaultFrom) (PR #2839) --- docusaurus/docs/cms/features/email.md | 28 +++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/docusaurus/docs/cms/features/email.md b/docusaurus/docs/cms/features/email.md index 1dc26c1856..4d3fa8b5e4 100644 --- a/docusaurus/docs/cms/features/email.md +++ b/docusaurus/docs/cms/features/email.md @@ -127,6 +127,10 @@ npm install @strapi/provider-email-sendgrid --save +:::tip Deliverability +For best deliverability, configure SPF/DKIM with your email provider and ensure the `defaultFrom` domain aligns with the domain you verified with the provider. +::: + ##### Configuring providers Newly installed providers are enabled and configured in [the `/config/plugins` file](/cms/configurations/plugins). If this file does not exist you must create it. @@ -226,6 +230,30 @@ module.exports = ({ env }) => ({ }, }, }); + + + + + +```ts title="/config/plugins.ts" +export default ({ env }) => ({ + email: { + config: { + provider: sendmail, // replace with your provider + providerOptions: { + // ... provider-specific options + }, + settings: { + defaultFrom: no-reply@example.com, + defaultReplyTo: support@example.com, + }, + }, + }, +}); +``` + + + ``` If your provider gives you a single URL instead of host and port values, pass that URL (for example `https://api.eu.mailgun.net`) in `providerOptions` using the key the package expects. From 6dc6430ece904743c0b9dab3c370a78c6a2cb605 Mon Sep 17 00:00:00 2001 From: GitHub Actions Date: Thu, 20 Nov 2025 20:55:43 +0000 Subject: [PATCH 16/17] Email docs: fix MDX/MD tab closure and quote literals; resolve Vercel build error (unexpected closing slash) --- docusaurus/docs/cms/features/email.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/docusaurus/docs/cms/features/email.md b/docusaurus/docs/cms/features/email.md index 4d3fa8b5e4..3fff40e67f 100644 --- a/docusaurus/docs/cms/features/email.md +++ b/docusaurus/docs/cms/features/email.md @@ -239,13 +239,13 @@ module.exports = ({ env }) => ({ export default ({ env }) => ({ email: { config: { - provider: sendmail, // replace with your provider + provider: 'sendmail', // replace with your provider providerOptions: { // ... provider-specific options }, settings: { - defaultFrom: no-reply@example.com, - defaultReplyTo: support@example.com, + defaultFrom: 'no-reply@example.com', + defaultReplyTo: 'support@example.com', }, }, }, @@ -254,8 +254,6 @@ export default ({ env }) => ({ -``` - If your provider gives you a single URL instead of host and port values, pass that URL (for example `https://api.eu.mailgun.net`) in `providerOptions` using the key the package expects. ##### Creating providers From 48d1a88efb5823c0441791119b1e71b39e89157a Mon Sep 17 00:00:00 2001 From: Pierre Wizla <4233866+pwizla@users.noreply.github.com> Date: Fri, 21 Nov 2025 15:17:39 +0100 Subject: [PATCH 17/17] Fix tabs --- docusaurus/docs/cms/features/email.md | 5 +++++ docusaurus/static/llms-code.txt | 21 +++++++++++++++++++++ docusaurus/static/llms-full.txt | 27 +++++---------------------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/docusaurus/docs/cms/features/email.md b/docusaurus/docs/cms/features/email.md index 3fff40e67f..852564ab88 100644 --- a/docusaurus/docs/cms/features/email.md +++ b/docusaurus/docs/cms/features/email.md @@ -209,6 +209,9 @@ You can set a specific configuration in the `/config/env/{env}/plugins.js|ts` co Some providers expose SMTP-style connection details instead of (or in addition to) an API key. Add those values in `providerOptions` so Strapi can reach the provider host. For instance, the community Nodemailer provider expects the host, port, and authentication credentials: + + + ```js title="/config/plugins.js" module.exports = ({ env }) => ({ email: { @@ -230,6 +233,7 @@ module.exports = ({ env }) => ({ }, }, }); +``` @@ -253,6 +257,7 @@ export default ({ env }) => ({ ``` + If your provider gives you a single URL instead of host and port values, pass that URL (for example `https://api.eu.mailgun.net`) in `providerOptions` using the key the package expects. diff --git a/docusaurus/static/llms-code.txt b/docusaurus/static/llms-code.txt index 8b9dde6887..ef000f2021 100644 --- a/docusaurus/static/llms-code.txt +++ b/docusaurus/static/llms-code.txt @@ -20889,6 +20889,27 @@ module.exports = ({ env }) => ({ }); ``` +--- +Language: TypeScript +File path: /config/plugins.ts + +```ts +export default ({ env }) => ({ + email: { + config: { + provider: 'sendmail', // replace with your provider + providerOptions: { + // ... provider-specific options + }, + settings: { + defaultFrom: 'no-reply@example.com', + defaultReplyTo: 'support@example.com', + }, + }, + }, +}); +``` + ## Creating providers Description: The interface that must be exported depends on the plugin you are developing the provider for. diff --git a/docusaurus/static/llms-full.txt b/docusaurus/static/llms-full.txt index beecbcb402..3506db3a69 100644 --- a/docusaurus/static/llms-full.txt +++ b/docusaurus/static/llms-full.txt @@ -8311,6 +8311,10 @@ The Email feature only handles outbound delivery. Receiving or parsing incoming +:::tip Deliverability +For best deliverability, configure SPF/DKIM with your email provider and ensure the `defaultFrom` domain aligns with the domain you verified with the provider. +::: + ##### Configuring providers Newly installed providers are enabled and configured in [the `/config/plugins` file](/cms/configurations/plugins). If this file does not exist you must create it. @@ -8335,28 +8339,7 @@ You can set a specific configuration in the `/config/env/{env}/plugins.js|ts` co Some providers expose SMTP-style connection details instead of (or in addition to) an API key. Add those values in `providerOptions` so Strapi can reach the provider host. For instance, the community Nodemailer provider expects the host, port, and authentication credentials: -```js title="/config/plugins.js" -module.exports = ({ env }) => ({ - email: { - config: { - provider: 'nodemailer', - providerOptions: { - host: env('SMTP_HOST'), - port: env.int('SMTP_PORT', 587), - secure: false, // Use `true` for port 465 - auth: { - user: env('SMTP_USERNAME'), - pass: env('SMTP_PASSWORD'), - }, - }, - settings: { - defaultFrom: 'no-reply@example.com', - defaultReplyTo: 'support@example.com', - }, - }, - }, -}); -``` + If your provider gives you a single URL instead of host and port values, pass that URL (for example `https://api.eu.mailgun.net`) in `providerOptions` using the key the package expects.