diff --git a/.github/workflows/deploy-production.yml b/.github/workflows/deploy-production.yml index 733879a8e5..3525cfd43a 100644 --- a/.github/workflows/deploy-production.yml +++ b/.github/workflows/deploy-production.yml @@ -56,4 +56,4 @@ jobs: algolia-app-id: ${{ secrets.ALGOLIA_APP_ID }} algolia-api-key: ${{ secrets.ALGOLIA_API_KEY }} site-url: 'https://docs.strapi.io' - crawler-name: 'strapiDocsNext' + crawler-name: 'v5-docs' diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000000..9f11b755a1 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.idea/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 142bb03ccb..258e9d58e2 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -45,6 +45,8 @@ The Strapi Documentation team has created a complete style guide for you to make 💁 While writing, please consider the [12 Rules of Technical Writing](https://handbook.strapi.io/user-success-manual/12-rules-of-technical-writing) that the Strapi Documentation team will use to assess the quality and consistency of the contribution. 😊 +⚠️ **Important: Please disable any linter or automatic formatting tool(s)** before saving and submitting your files. Not doing so could, at best, add unnecessary formatting changes to the submitted PR or, at worst, prevent Docusaurus from properly rendering some pages. + ### Working locally: Set up the project To set up the Docusaurus project on your machine, perform the following steps from a terminal instance: @@ -94,7 +96,7 @@ To submit your contribution for review: **⚠️ Important: Add the `flag: merge pending release` if the Strapi Documentation team should wait before merging the pull request.** Approved pull requests are usually merged immediately into the `main` branch, automatically triggering a deployment on docs.strapi.io. Please use the `flag: merge pending release` label if the pull request content should only be released publicly in sync with a product release (e.g., if you submit a pull request to document a contribution to the `strapi/strapi` repository). -That’s it! 🥳 Once the pull request is [reviewed and approved](#review-and-management-of-pull-requests), the Strapi Documentation team will merge it, and the content will be live on [docs.strapi.io](http://docs.strapi.io) a few minutes later. 🚀 +That’s it! 🥳 Once the pull request is [reviewed and approved](#review-and-management-of-pull-requests), the Strapi Documentation team will merge it, and the content will be live on [docs.strapi.io](http://docs.strapi.io) a few minutes later. 🚀 Please note that the title of your PR might be rewritten to increase clarity for inclusion in the [release notes](docs.strapi.io/release-notes). ## Review and management of pull requests diff --git a/LICENSE b/LICENSE index db018546b5..c0bece5197 100644 --- a/LICENSE +++ b/LICENSE @@ -1,10 +1,6 @@ Copyright (c) 2015-present Strapi Solutions SAS -Portions of the Strapi software are licensed as follows: - -* All software that resides under an "ee/" directory (the “EE Software”), if that directory exists, is licensed under the license defined in "ee/LICENSE". - -* All software outside of the above-mentioned directories or restrictions above is available under the "MIT Expat" license as set forth below. +* All software is available under the "MIT Expat" license as set forth below. MIT Expat License diff --git a/README.md b/README.md index 1361189a67..98d1625009 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ The main official Strapi documentation website is hosted at [docs.strapi.io](htt Additional official Strapi documentation websites cover different content: - Documentation for the older version 4 of Strapi is hosted at [docs-v4.strapi.io](https://docs-v4.strapi.io) and featured in the `v4` branch. This branch is not actively maintained by the Strapi Documentation team, but community contributions are most welcome! -- Upcoming and/or experimental documentation is hosted at [docs-next.strapi.io](https://docs-next.strapi.io). Starting autumn/winter 2024, this website will include an all-new documentation — more info soon! +- Upcoming, experimental documentation is hosted at [docs-next.strapi.io](https://docs-next.strapi.io). Starting autumn/winter 2024, this website will include an all-new documentation — more info soon! - Documentation for the older, unsupported version 3 of Strapi is hosted at [docs-v3.strapi.io](https://docs-v3.strapi.io). - Documentation for contributors, which include more in-depth and experimental content for developers who actively maintain and contribute to Strapi, is hosted at [contributor.strapi.io](https://contributor.strapi.io). This experimental documentation is maintained by Strapi engineers and any issue should be reported to the [`strapi/strapi`](https://github.com/strapi/strapi/issues/new/choose) repository. - Documentation for the Strapi Design System is hosted at [design-system.strapi.io](https://design-system.strapi.io/) and maintained by Strapi front-end engineers in its [dedicated repository](https://github.com/strapi/design-system/). diff --git a/docusaurus/docs/cloud/account/account-billing.md b/docusaurus/docs/cloud/account/account-billing.md index 6d504acdb6..3e4c1f41bc 100644 --- a/docusaurus/docs/cloud/account/account-billing.md +++ b/docusaurus/docs/cloud/account/account-billing.md @@ -46,7 +46,8 @@ The *Payment method* section of the ![Billing icon](/img/assets/icons/CreditCard 3. Click on the **Save** button. :::tip -The first credit card to be added as payment method for the account will by default be the primary one. It is however possible to define another credit card as primary by clicking on the ![Menu icon](/img/assets/icons/more.svg) icon, then **Switch as primary**. +- The first credit card to be added as payment method will be by default the primary card. You can change the role by clicking on the ![Menu icon](/img/assets/icons/more.svg) icon, then **Set as primary** on another card. +- Be aware that you also have the possibility to use a dedicated card at projects-level. It will allow you to use different cards for different projects (see [Project Settings > Billing & Usage](/cloud/projects/settings#billing--usage)). ::: ### Deleting a credit card diff --git a/docusaurus/docs/cloud/advanced/database.md b/docusaurus/docs/cloud/advanced/database.md index c5d7def61f..27e5648796 100644 --- a/docusaurus/docs/cloud/advanced/database.md +++ b/docusaurus/docs/cloud/advanced/database.md @@ -30,9 +30,12 @@ While it's possible to use an external database with Strapi Cloud, you should do - Strapi can't provide security or support with external databases used with Strapi Cloud. ::: - ## Configuration +:::caution +To ensure a smooth deployment, it is recommended to not change the names of the environment variables. +::: + The project `./config/database.js` or `./config/database.ts` file must match the configuration found in the [environment variables in database configurations](https://docs.strapi.io/dev-docs/configurations/database#environment-variables-in-database-configurations) section. Before pushing changes, add environment variables to the Strapi Cloud project: @@ -54,10 +57,6 @@ Before pushing changes, add environment variables to the Strapi Cloud project: 4. Click **Save**. -:::caution -To ensure a smooth deployment, it is recommended to not change the names of the environment variables. -::: - ## Deployment To deploy the project and utilize the external database, push the changes from earlier. This will trigger a rebuild and new deployment of the Strapi Cloud project. diff --git a/docusaurus/docs/cloud/advanced/email.md b/docusaurus/docs/cloud/advanced/email.md index b8613a5e26..c4e40eafb6 100644 --- a/docusaurus/docs/cloud/advanced/email.md +++ b/docusaurus/docs/cloud/advanced/email.md @@ -42,7 +42,11 @@ Using either `npm` or `yarn`, install the provider plugin in your local Strapi p ### Configure the Provider -In your Strapi project, create a `./config/env/production/plugins.js` or `./config/env/production/plugins.ts` file with the following content: +:::caution +The file structure must match the below path **exactly**, or the configuration will not be applied to Strapi Cloud. +::: + +To configure a 3rd-party email provider in your Strapi project, create or edit the plugins configuration file for your production environment `./config/env/production/plugins.js|ts` by adding upload configuration options as follows: @@ -84,10 +88,6 @@ export default ({ env }) => ({ -:::caution -The file structure must match the above path exactly, or the configuration will not be applied to Strapi Cloud. -::: - Each provider will have different configuration settings available. Review the respective entry for that provider in the [Marketplace](https://market.strapi.io/providers). **Example:** diff --git a/docusaurus/docs/cloud/advanced/upload.md b/docusaurus/docs/cloud/advanced/upload.md index 6ddc24043a..b61dbbe5f8 100644 --- a/docusaurus/docs/cloud/advanced/upload.md +++ b/docusaurus/docs/cloud/advanced/upload.md @@ -44,6 +44,10 @@ Using either `npm` or `yarn`, install the provider plugin in your local Strapi p ### Configure the Provider +:::caution +The file structure must match the below path **exactly**, or the configuration will not be applied to Strapi Cloud. +::: + To configure a 3rd-party upload provider in your Strapi project, create or edit the plugins configuration file for your production environment `./config/env/production/plugins.js|ts` by adding upload configuration options as follows: @@ -85,10 +89,6 @@ upload: { -:::caution -The file structure must match the above path exactly, or the configuration will not be applied to Strapi Cloud. -::: - Each provider will have different configuration settings available. Review the respective entry for that provider in the [Marketplace](https://market.strapi.io/providers). **Example:** diff --git a/docusaurus/docs/cloud/cli/cloud-cli.md b/docusaurus/docs/cloud/cli/cloud-cli.md index 8b957f57fe..d4d4b8ab5d 100644 --- a/docusaurus/docs/cloud/cli/cloud-cli.md +++ b/docusaurus/docs/cloud/cli/cloud-cli.md @@ -9,7 +9,7 @@ tags: pagination_next: cloud/advanced/database --- -# Command Line Interface (CLI) +# Command Line Interface (CLI) Strapi Cloud comes with a Command Line Interface (CLI) which allows you to log in and out, and to deploy a local project without it having to be hosted on a remote git repository. The CLI works with both the `yarn` and `npm` package managers. @@ -41,14 +41,20 @@ Deploy a new local project (< 100MB) in Strapi Cloud. strapi deploy ``` -This command must be used after the `login` one. It deploys a local Strapi project on Strapi Cloud, without having to host it on a remote git repository beforehand. The terminal will inform you when the project is successfully deployed on Strapi Cloud. +This command must be used after the `login` one. It deploys a local Strapi project on Strapi Cloud, without having to host it on a remote git repository beforehand. -Once the project is first deployed on Strapi Cloud with the CLI, the `deploy` command can be reused to trigger a new deployment of the same project. - -:::caution -The `deploy` command can only be used by new users who have never created a Strapi Cloud project, and for which the free trial is still available. Once a project is deployed with the CLI, it isn't possible to deploy another project on the same Strapi Cloud account with the CLI. +:::note +If you have any free trial available, the deploy command will create automatically a new project on Strapi Cloud, unless you previously link your local project to an existing project by using the `strapi link` command. ::: +When you use this command, you’ll be asked to select a target environment. To skip this prompt, you can either: +- Use the `--env` flag (e.g., `strapi deploy --env `) +- Set a default environment with `strapi cloud environment link` [command](#cloud-environment-link), so deployments automatically go to that environment. + +The terminal will inform you when the project is successfully deployed on Strapi Cloud. + +Once the project is first deployed on Strapi Cloud with the CLI, the `deploy` command can be reused to trigger a new deployment of the same project. + :::note Once you deployed your project, if you visit the Strapi Cloud dashboard, you may see some limitations as well as impacts due to creating a Strapi Cloud project that is not in a remote repository and which was deployed with the CLI. @@ -56,19 +62,23 @@ Once you deployed your project, if you visit the Strapi Cloud dashboard, you may - Some buttons, such as the **Trigger deploy** button, will be greyed out and unclickable since, unless you have [connected a git repository to your Strapi Cloud project](/cloud/getting-started/deployment-cli#automatically-deploying-subsequent-changes). ::: -## strapi link +## strapi link **Alias:** `strapi cloud:link` Links project in current folder to an existing project in Strapi Cloud. +:::note +Linking a project to Strapi Cloud doesn't limit it to Strapi Cloud alone; you can still deploy and manage it in your own self-hosted environment as needed. +::: + ```bash strapi link ``` This command connects your local project in the current directory with an existing project on your Strapi Cloud account. You will be prompted to select the project you wish to link from a list of available projects hosted on Strapi Cloud. -## strapi projects +## strapi projects **Alias:** `strapi cloud:projects` @@ -78,7 +88,34 @@ Lists all Strapi Cloud projects associated with your account. strapi projects ``` -This command retrieves and displays a list of all projects hosted on your Strapi Cloud account. + +```bash +strapi link +``` + +This command connects your local project in the current directory with an existing project on your Strapi Cloud account. You will be prompted to select the project you wish to link from a list of available projects hosted on Strapi Cloud. + +## strapi cloud environments {#cloud-environments} + +**Alias:** `strapi cloud environment list` + +Lists all environments associated with your Strapi Cloud Project. + +```bash +strapi cloud environments +``` + +This command retrieves and displays a list of all environments belonging to your Strapi Cloud project. + +## strapi cloud environment link {#cloud-environment-link} + +Links your local project to a specific environment in your Strapi Cloud project. + +```bash +strapi cloud environment link +``` + +This command shows a list of all environments in your Strapi Cloud project and lets you choose one. The selected environment will then be the default for direct deployments. ## strapi logout diff --git a/docusaurus/docs/cloud/getting-started/deployment.md b/docusaurus/docs/cloud/getting-started/deployment.md index 1ce25f7973..eb04525d1d 100644 --- a/docusaurus/docs/cloud/getting-started/deployment.md +++ b/docusaurus/docs/cloud/getting-started/deployment.md @@ -144,10 +144,10 @@ Before you can deploy your Strapi application on Strapi Cloud using the Cloud da | Setting name | Instructions | |--------------|---------------------------------------------------------------------------------------------------------| - | Display name | Write the name of your Strapi app, this is fetched from the repository name but can be edited. It is automatically converted to slug format (`my-strapi-app`). | + | Display name | Write the name of your Strapi app, this is fetched from the repository name but can be edited.
It is automatically converted to slug format (`my-strapi-app`). | | Git branch | Choose from the drop-down the default branch to use for this deployment. This uses the default branch of the repository. | | Deploy on push | Check the box to automatically deploy the latest changes from the selected branch. When disabled, you will need to manually deploy the latest changes. | - | Region | Choose the geographic location of the servers where your Strapi application is hosted. Selected region can either be New York in North America (default) or Amsterdam in Europe. | + | Region | Choose the geographic location of the servers where your Strapi application is hosted. Selected region can either be New York in North America (default), Amsterdam in Europe, Singapore in Asia or Sydney in Oceania. | :::note The Git branch and "Deploy on push" settings can be modified afterwards through the project's setting, however the project name and hosting region setting can only be chosen during the creation of the project (see [Project Settings](/cloud/projects/settings)). diff --git a/docusaurus/docs/cloud/getting-started/usage-billing.md b/docusaurus/docs/cloud/getting-started/usage-billing.md index aa9570ec00..a54e775455 100644 --- a/docusaurus/docs/cloud/getting-started/usage-billing.md +++ b/docusaurus/docs/cloud/getting-started/usage-billing.md @@ -19,7 +19,7 @@ Strapi Cloud offers a free 14 days trial for all new accounts, and 3 paid plans: | Feature | Free Trial | Developer | Pro | Team | | --- | --- | --- | --- | --- | -| **Seats** | 10 (up to 10 extra) | 1 (up to 3 extra) | 5 (up to 20 extra) | 10 (up to 50 extra) | +| **Seats** | 10 | 1 (up to 2 extra) | 5 (up to 15 extra) | 10 (up to 40 extra) | | **Database Entries** | 1,000 | 1,000 | 100,000 | 1,000,000 | | **Assets Storage** | 5GB | 15GB | 150GB | 500GB | | **Assets Bandwidth** | 50GB | 50GB per month | 500GB per month | 1,000GB per month | diff --git a/docusaurus/docs/cloud/projects/runtime-logs.md b/docusaurus/docs/cloud/projects/runtime-logs.md index e4cb2fd759..f4b3cc43e9 100644 --- a/docusaurus/docs/cloud/projects/runtime-logs.md +++ b/docusaurus/docs/cloud/projects/runtime-logs.md @@ -9,8 +9,6 @@ tags: - Strapi Cloud --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Runtime logs From a chosen project's dashboard, the *Runtime logs* tab displays the live logs of the project. diff --git a/docusaurus/docs/cloud/projects/settings.md b/docusaurus/docs/cloud/projects/settings.md index 47b7b202ab..ee62126627 100644 --- a/docusaurus/docs/cloud/projects/settings.md +++ b/docusaurus/docs/cloud/projects/settings.md @@ -23,13 +23,13 @@ The settings' menu on the left side of the interface is separated into 2 categor ## Project-level settings There are 5 tabs available for the project's settings: -- ![General icon](/img/assets/icons/Faders.svg) [*General (project)*](#general), +- ![General icon](/img/assets/icons/Faders.svg) [*General*](#general), - ![Environments icon](/img/assets/icons/v5/Stack.svg) [*Environments*](#environments), - ![Billing & Usage icon](/img/assets/icons/CreditCard.svg) [*Billing & Usage*](#billing--usage), - ![Plans icon](/img/assets/icons/MapTrifold.svg) [Plans](#plans), - and ![Invoices icon](/img/assets/icons/Invoice.svg) [Invoices](#invoices). -### General (project) +### General The ![General icon](/img/assets/icons/Faders.svg) *General* tab for the project-level settings enables you to check and update the following options for the project: @@ -74,7 +74,7 @@ Updating the git repository could result in the loss of the project and its data | Auto-deploy | Tick the box to automatically trigger a new deployment whenever a new commit is pushed to the selected branch. Untick it to disable the option. | 5. Click on the **Update repository** button at the bottom of the *Update repository* interface. -6. In the *Manage repository* dialog, confirm your changes by clicking on the **Relink repository** button. +6. In the *Update repository* dialog, confirm your changes by clicking on the **Confirm** button. #### Deleting Strapi Cloud project @@ -125,7 +125,11 @@ The ![Billing & Usage icon](/img/assets/icons/CreditCard.svg) *Billing & Usage* Through this tab, you also have the possibility to: - click the **Change** button to be redirected to the ![Plans icon](/img/assets/icons/MapTrifold.svg) *Plans* tab, where you can change you subscription plan ([see related documentation](#plans)), -- click the **Edit** button to be redirected to the ![Billing icon](/img/assets/icons/CreditCard.svg) *Billing* tab of your profile page, where you can edit the payment method (see [related documentation](/cloud/account/account-billing)). +- click the **Edit** button in order to set a new payment method (see [related documentation](/cloud/account/account-billing)). + +:::note +You can attach a dedicated card to your project by choosing the payment method directly from this page. In that way, you can manage your subscriptions with different cards. +::: :::tip In the Usage section of the ![Billing & Usage icon](/img/assets/icons/CreditCard.svg) *Billing & Usage* tab, you can see the current monthly usage of your project compared to the maximum usage allowed by your project's subscription. Use the arrows in the top right corner to see the project's usage for any chosen month. @@ -235,20 +239,20 @@ In the *Profile > Invoices* tab, you will find the complete list of invoices for In the project's environments' settings, you first need to select the environment whose settings you would like to configure, using the dropdown. Depending on the chosen environment, there are 3 to 4 tabs available: -- ![General icon](/img/assets/icons/Faders.svg) [*General (environment)*](#general), +- ![General icon](/img/assets/icons/Faders.svg) [*Configuration*](#configuration), - ![Backups icon](/img/assets/icons/ArrowClockwise.svg) [*Backups*](#backups), which are only available for the production environment, - ![Domains icon](/img/assets/icons/Browsers.svg) [*Domains*](#domains), - and ![Variables icon](/img/assets/icons/code2.svg) [*Variables*](#variables). -### General (environment) +### Configuration -The ![General icon](/img/assets/icons/Faders.svg) *General* tab for the environment-level settings enables you to check and update the following options for the project: +The ![General icon](/img/assets/icons/Faders.svg) *Configuration* tab for the environment-level settings enables you to check and update the following options for the project: - *Basic information*, to see: - the name of your Strapi Cloud project's environment. The environment name is set when it is created and cannot be modified afterwards. - the Node version of the environment: to change the Node version of the project (see [Modifying Node version](#modifying-node-version)). - the app's internal name for the environment, which can be useful for debug & support purposes. -- *Connect branch*: to change the branch of the GitHub repository used for your environment (see [Editing Git branch](#editing-git-branch)). Also allows to enable/disable the "deploy on push" option. +- *Connected branch*: to change the branch of the GitHub repository used for your environment (see [Editing Git branch](#editing-git-branch)). Also allows to enable/disable the "deploy on push" option. - *Danger zone*: to reset or permanently delete your Strapi Cloud project's environment (see [Resetting & Deleting environment](#resetting--deleting-environment)). +Example: Customizing some admin panel colors: + +With the following code example, buttons and links that would use some primary colors will be displayed in red, as shown in the example screenshot: + + + + + +```tsx title="/src/admin/app.js" +export default { + config: { + theme: { + light: { + colors: { + primary600: "red", + buttonPrimary500: "red", + buttonPrimary600: "red", + }, + }, + }, + }, + bootstrap() {}, +}; +``` + + + + + +```tsx title="/src/admin/app.ts" +import type { StrapiApp } from "@strapi/strapi/admin"; + +export default { + config: { + theme: { + light: { + colors: { + primary600: "red", + buttonPrimary500: "red", + buttonPrimary600: "red", + }, + }; + }, + }, + bootstrap (app: StrapiApp) {}, +} +``` + + + + +![Custom buttons in red](/img/assets/admin-panel-customization/red-login-button.png) + diff --git a/docusaurus/docs/dev-docs/api/document-service.md b/docusaurus/docs/dev-docs/api/document-service.md index 78825a0e75..62db443c9a 100644 --- a/docusaurus/docs/dev-docs/api/document-service.md +++ b/docusaurus/docs/dev-docs/api/document-service.md @@ -634,7 +634,7 @@ If no `locale` parameter is passed, `discardDraft()` discards draft data and ove ```js -strapi.documents.discardDraft({ +strapi.documents('api::restaurant.restaurant').discardDraft({ documentId: 'a1b2c3d4e5f6g7h8i9j0klm', }); ``` diff --git a/docusaurus/docs/dev-docs/api/document-service/status.md b/docusaurus/docs/dev-docs/api/document-service/status.md index 35c581660c..1779c28d26 100644 --- a/docusaurus/docs/dev-docs/api/document-service/status.md +++ b/docusaurus/docs/dev-docs/api/document-service/status.md @@ -198,8 +198,8 @@ To automatically publish a document while updating it, add `status: 'published'` ```js await strapi.documents('api::restaurant.restaurant').update({ + documentId: 'a1b2c3d4e5f6g7h8i9j0klm', data: { - documentId: 'a1b2c3d4e5f6g7h8i9j0klm', name: "Biscotte Restaurant (closed)", }, status: 'published', diff --git a/docusaurus/docs/dev-docs/api/entity-service.md b/docusaurus/docs/dev-docs/api/entity-service.md index 3f60915a9e..12ff3d0445 100644 --- a/docusaurus/docs/dev-docs/api/entity-service.md +++ b/docusaurus/docs/dev-docs/api/entity-service.md @@ -7,7 +7,6 @@ unlisted: true import EntityQueryKnex from '/docs/snippets/entity-query-knex.md' import BackendIntroCrosslink from '/docs/snippets/backend-custom-intro-crosslink.md' -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ESdeprecated from '/docs/snippets/entity-service-deprecated.md' # Entity Service API diff --git a/docusaurus/docs/dev-docs/api/graphql.md b/docusaurus/docs/dev-docs/api/graphql.md index b5a3ab11d0..899516c8b8 100644 --- a/docusaurus/docs/dev-docs/api/graphql.md +++ b/docusaurus/docs/dev-docs/api/graphql.md @@ -15,8 +15,6 @@ tags: - sort --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # GraphQL API The GraphQL API allows performing queries and mutations to interact with the [content-types](/dev-docs/backend-customization/models#content-types) through Strapi's [GraphQL plugin](/dev-docs/plugins/graphql.md). Results can be [filtered](#filters), [sorted](#sorting) and [paginated](#pagination). diff --git a/docusaurus/docs/dev-docs/api/query-engine/bulk-operations.md b/docusaurus/docs/dev-docs/api/query-engine/bulk-operations.md index a6ef42e5c0..006edd7a50 100644 --- a/docusaurus/docs/dev-docs/api/query-engine/bulk-operations.md +++ b/docusaurus/docs/dev-docs/api/query-engine/bulk-operations.md @@ -13,7 +13,6 @@ tags: - updateMany() --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ConsiderDocumentService from '/docs/snippets/consider-document-service.md' # Bulk Operations with the Query Engine API diff --git a/docusaurus/docs/dev-docs/api/query-engine/filtering.md b/docusaurus/docs/dev-docs/api/query-engine/filtering.md index 9f51157600..4a00923efc 100644 --- a/docusaurus/docs/dev-docs/api/query-engine/filtering.md +++ b/docusaurus/docs/dev-docs/api/query-engine/filtering.md @@ -11,7 +11,6 @@ tags: - Query Engine API --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ConsiderDocumentService from '/docs/snippets/consider-document-service.md' # Filtering with the Query Engine API diff --git a/docusaurus/docs/dev-docs/api/rest.md b/docusaurus/docs/dev-docs/api/rest.md index 5e3a535236..de42dbe515 100644 --- a/docusaurus/docs/dev-docs/api/rest.md +++ b/docusaurus/docs/dev-docs/api/rest.md @@ -62,11 +62,11 @@ sources={{ | Method | URL | Description | | -------- | ------------------------------- | ------------------------------------- | -| `GET` | `/api/:pluralApiId` | [Get a list of document](#get-documents) | -| `POST` | `/api/:pluralApiId` | [Create a document](#create-an-entry) | -| `GET` | `/api/:pluralApiId/:documentId` | [Get a document](#get-an-entry) | -| `PUT` | `/api/:pluralApiId/:documentId` | [Update a document](#update-an-entry) | -| `DELETE` | `/api/:pluralApiId/:documentId` | [Delete a document](#delete-an-entry) | +| `GET` | `/api/:pluralApiId` | [Get a list of document](#get-all) | +| `POST` | `/api/:pluralApiId` | [Create a document](#create) | +| `GET` | `/api/:pluralApiId/:documentId` | [Get a document](#get) | +| `PUT` | `/api/:pluralApiId/:documentId` | [Update a document](#update) | +| `DELETE` | `/api/:pluralApiId/:documentId` | [Delete a document](#delete) | @@ -150,10 +150,6 @@ Requests return a response as an object which usually includes the following key Some plugins (including Users & Permissions and Upload) may not follow this response format. ::: - - - - ### Get documents {#get-all} Returns documents matching the query filters (see [API parameters](/dev-docs/api/rest/parameters) documentation). @@ -164,10 +160,6 @@ In Strapi 5 the response format has been flattened, and attributes are directly You can pass an optional header while you're migrating to Strapi 5 (see the [related breaking change](/dev-docs/migration/v4-to-v5/breaking-changes/new-response-format)). ::: - - - - @@ -227,14 +219,6 @@ You can pass an optional header while you're migrating to Strapi 5 (see the [rel - - - - - - - - ### Get a document {#get} Returns a document by `documentId`. @@ -243,10 +227,6 @@ Returns a document by `documentId`. In Strapi 5, a specific document is reached by its `documentId`. ::: - - - - @@ -288,28 +268,18 @@ In Strapi 5, a specific document is reached by its `documentId`. - - - - - - - - ### Create a document {#create} Creates a document and returns its value. -If the [Internationalization (i18n) plugin](/dev-docs/i18n) is installed, it's possible to use POST requests to the REST API to [create localized documents](/dev-docs/i18n#creating-a-new-localized-entry). +By default, a document is created with a published status. To create a document as a draft, pass the [`status`](/dev-docs/api/rest/filters-locale-publication#status) query parameter with the value `draft` (e.g., `?status=draft`). + +If the Internationalization (i18n) feature is enabled on the content-type, it's possible to use POST requests to the REST API to [create localized documents](/dev-docs/i18n#creating-a-new-localized-entry). :::note While creating a document, you can define its relations and their order (see [Managing relations through the REST API](/dev-docs/api/rest/relations.md) for more details). ::: - - - - @@ -368,14 +338,6 @@ While creating a document, you can define its relations and their order (see [Ma - - - - - - - - ### Update a document {#update} Partially updates a document by `id` and returns its value. @@ -388,10 +350,6 @@ Send a `null` value to clear fields. * While updating a document, you can define its relations and their order (see [Managing relations through the REST API](/dev-docs/api/rest/relations) for more details). ::: - - - - @@ -451,22 +409,12 @@ Send a `null` value to clear fields. - - - - - - - ### Delete a document {#delete} Deletes a document. `DELETE` requests only send a 204 HTTP status code on success and do not return any data in the response body. - - - @@ -476,6 +424,3 @@ Deletes a document. - - - diff --git a/docusaurus/docs/dev-docs/api/rest/filters-locale-publication.md b/docusaurus/docs/dev-docs/api/rest/filters-locale-publication.md index 16a25ea581..2b21338b55 100644 --- a/docusaurus/docs/dev-docs/api/rest/filters-locale-publication.md +++ b/docusaurus/docs/dev-docs/api/rest/filters-locale-publication.md @@ -19,7 +19,6 @@ tags: import QsIntroFull from '/docs/snippets/qs-intro-full.md' import QsForQueryBody from '/docs/snippets/qs-for-query-body.md' import QsForQueryTitle from '/docs/snippets/qs-for-query-title.md' -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' # REST API: Filtering, Locale, and Publication State @@ -72,17 +71,11 @@ The following operators are available: By default, the filters can only be used from `find` endpoints generated by the Content-type Builder and the CLI. ::: - - ### Example: Find users having 'John' as a first name You can use the `$eq` filter operator to find an exact match. - - - -
@@ -92,6 +85,28 @@ You can use the `$eq` filter operator to find an exact match.
+
+ + + + +```js +const qs = require('qs'); +const query = qs.stringify({ + filters: { + username: { + $eq: 'John', + }, + }, +}, { + encodeValuesOnly: true, // prettify URL +}); + +await request(`/api/users?${query}`); +``` + +
+ ```json @@ -122,6 +137,20 @@ You can use the `$eq` filter operator to find an exact match. + +### Example: Find multiple restaurants with ids 3, 6,8 + +You can use the `$in` filter operator with an array of values to find multiple exact values. + +
+ + + + +`GET /api/restaurants?filters[id][$in][0]=6&filters[id][$in][1]=8` + + +
@@ -131,42 +160,19 @@ You can use the `$eq` filter operator to find an exact match. const qs = require('qs'); const query = qs.stringify({ filters: { - username: { - $eq: 'John', + id: { + $in: [3, 6, 8], }, }, }, { encodeValuesOnly: true, // prettify URL }); -await request(`/api/users?${query}`); +await request(`/api/restaurants?${query}`); ```
- - - - - - -### Example: Find multiple restaurants with ids 3, 6,8 - -You can use the `$in` filter operator with an array of values to find multiple exact values. - - - - - -
- - - - -`GET /api/restaurants?filters[id][$in][0]=6&filters[id][$in][1]=8` - - - ```json @@ -194,42 +200,10 @@ You can use the `$in` filter operator with an array of values to find multiple e -
- - - - -```js -const qs = require('qs'); -const query = qs.stringify({ - filters: { - id: { - $in: [3, 6, 8], - }, - }, -}, { - encodeValuesOnly: true, // prettify URL -}); - -await request(`/api/restaurants?${query}`); -``` - -
- -
-
- - - - ### Complex filtering Complex filtering is combining multiple filters using advanced methods such as combining `$and` & `$or`. This allows for more flexibility to request exactly the data needed. - - - -
@@ -238,35 +212,6 @@ Complex filtering is combining multiple filters using advanced methods such as c - - -```json -{ - "data": [ - { - "id": 1, - "documentId": "rxngxzclq0zdaqtvz67hj38d", - "name": "test1", - "date": "2020-01-01", - // ... - }, - { - "id": 2, - "documentId": "kjkhff4e269a50b4vi16stst", - "name": "test2", - "date": "2020-01-02", - // ... - } - ], - "meta": { - // ... - } -} -``` - - - -
@@ -303,11 +248,34 @@ await request(`/api/books?${query}`);
-
-
+ - - +```json +{ + "data": [ + { + "id": 1, + "documentId": "rxngxzclq0zdaqtvz67hj38d", + "name": "test1", + "date": "2020-01-01", + // ... + }, + { + "id": 2, + "documentId": "kjkhff4e269a50b4vi16stst", + "name": "test2", + "date": "2020-01-02", + // ... + } + ], + "meta": { + // ... + } +} +``` + + +
### Deep filtering @@ -329,10 +297,6 @@ Deep filtering is filtering on a relation's fields. ::: - - - -
@@ -342,6 +306,32 @@ Deep filtering is filtering on a relation's fields. +
+ + + + +```js +const qs = require('qs'); +const query = qs.stringify({ + filters: { + chef: { + restaurants: { + stars: { + $eq: 5, + }, + }, + }, + }, +}, { + encodeValuesOnly: true, // prettify URL +}); + +await request(`/api/restaurants?${query}`); +``` + +
+ ```json @@ -371,35 +361,6 @@ Deep filtering is filtering on a relation's fields.
-
- - - - -```js -const qs = require('qs'); -const query = qs.stringify({ - filters: { - chef: { - restaurants: { - stars: { - $eq: 5, - }, - }, - }, - }, -}, { - encodeValuesOnly: true, // prettify URL -}); - -await request(`/api/restaurants?${query}`); -``` - -
- -
- - ## Locale :::prerequisites @@ -410,9 +371,6 @@ await request(`/api/restaurants?${query}`); The `locale` API parameter can be used to work with entries from a specific locale (see [Internationalization documentation](/dev-docs/i18n#rest)). - - - ## Status :::prerequisites @@ -432,10 +390,6 @@ In the response data, the `publishedAt` field is `null` for drafts. Since published versions are returned by default, passing no status parameter is equivalent to passing `status=published`. ::: - - - -

@@ -444,6 +398,25 @@ Since published versions are returned by default, passing no status parameter is `GET /api/articles?status=draft` + +
+ + + + +```js +const qs = require('qs'); +const query = qs.stringify({ + status: 'draft', +}, { + encodeValuesOnly: true, // prettify URL +}); + +await request(`/api/articles?${query}`); +``` + +
+ ```json {21} @@ -485,24 +458,3 @@ Since published versions are returned by default, passing no status parameter is
- -
- - - - -```js -const qs = require('qs'); -const query = qs.stringify({ - status: 'draft', -}, { - encodeValuesOnly: true, // prettify URL -}); - -await request(`/api/articles?${query}`); -``` - -
- -
-
diff --git a/docusaurus/docs/dev-docs/api/rest/guides/intro.md b/docusaurus/docs/dev-docs/api/rest/guides/intro.md index 2adfb98597..74e004995e 100644 --- a/docusaurus/docs/dev-docs/api/rest/guides/intro.md +++ b/docusaurus/docs/dev-docs/api/rest/guides/intro.md @@ -35,6 +35,8 @@ Additional tutorials and guides can be found in the following blog posts: + + diff --git a/docusaurus/docs/dev-docs/api/rest/guides/populate-creator-fields.md b/docusaurus/docs/dev-docs/api/rest/guides/populate-creator-fields.md index 582baf8c92..7084812cb5 100644 --- a/docusaurus/docs/dev-docs/api/rest/guides/populate-creator-fields.md +++ b/docusaurus/docs/dev-docs/api/rest/guides/populate-creator-fields.md @@ -13,12 +13,8 @@ tags: - updatedBy --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # 🛠️ How to populate creator fields such as `createdBy` and `updatedBy` - - The creator fields `createdBy` and `updatedBy` are removed from the [REST API](/dev-docs/api/rest) response by default. These 2 fields can be returned in the REST API by activating the `populateCreatorFields` parameter at the content-type level. :::note diff --git a/docusaurus/docs/dev-docs/api/rest/guides/understanding-populate.md b/docusaurus/docs/dev-docs/api/rest/guides/understanding-populate.md index 03d9884dc5..00fb123b16 100644 --- a/docusaurus/docs/dev-docs/api/rest/guides/understanding-populate.md +++ b/docusaurus/docs/dev-docs/api/rest/guides/understanding-populate.md @@ -17,13 +17,10 @@ tags: import QsIntroFull from '/docs/snippets/qs-intro-full.md' import QsForQueryTitle from '/docs/snippets/qs-for-query-title.md' import QsForQueryBody from '/docs/snippets/qs-for-query-body.md' -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ScreenshotNumberReference from '/src/components/ScreenshotNumberReference.jsx'; # 🧠 Understanding the `populate` parameter for the REST API - - :::note Note: Example responses might differ from your experience The content of this page might not be fully up-to-date with Strapi 5 yet: diff --git a/docusaurus/docs/dev-docs/api/rest/interactive-query-builder.md b/docusaurus/docs/dev-docs/api/rest/interactive-query-builder.md index bf54950eee..0ea2837554 100644 --- a/docusaurus/docs/dev-docs/api/rest/interactive-query-builder.md +++ b/docusaurus/docs/dev-docs/api/rest/interactive-query-builder.md @@ -47,7 +47,7 @@ Please refer to the [REST API parameters table](/dev-docs/api/rest/parameters) a page: 1, }, status: 'published', - locale: ['en'], + locale: 'en', } `} /> diff --git a/docusaurus/docs/dev-docs/api/rest/parameters.md b/docusaurus/docs/dev-docs/api/rest/parameters.md index 2c4f64ff7f..66f8bfa16f 100644 --- a/docusaurus/docs/dev-docs/api/rest/parameters.md +++ b/docusaurus/docs/dev-docs/api/rest/parameters.md @@ -14,8 +14,6 @@ tags: - status --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # REST API parameters API parameters can be used with the [REST API](/dev-docs/api/rest) to filter, sort, and paginate results and to select fields and relations to populate. Additionally, specific parameters related to optional Strapi features can be used, like the publication state and locale of a content-type. diff --git a/docusaurus/docs/dev-docs/api/rest/populate-select.md b/docusaurus/docs/dev-docs/api/rest/populate-select.md index 3f4049e1d3..78c38f3ed3 100644 --- a/docusaurus/docs/dev-docs/api/rest/populate-select.md +++ b/docusaurus/docs/dev-docs/api/rest/populate-select.md @@ -17,7 +17,6 @@ tags: import QsIntroFull from '/docs/snippets/qs-intro-full.md' import QsForQueryTitle from '/docs/snippets/qs-for-query-title.md' import QsForQueryBody from '/docs/snippets/qs-for-query-body.md' -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' # REST API: Population & Field Selection @@ -58,6 +57,27 @@ Field selection does not work on relational, media, component, or dynamic zone f +
+ + + + +```js +const qs = require('qs'); +const query = qs.stringify( + { + fields: ['name', 'description'], + }, + { + encodeValuesOnly: true, // prettify URL + } +); + +await request(`/api/users?${query}`); +``` + +
+ ```json @@ -95,27 +115,6 @@ Field selection does not work on relational, media, component, or dynamic zone f -
- - - - -```js -const qs = require('qs'); -const query = qs.stringify( - { - fields: ['name', 'description'], - }, - { - encodeValuesOnly: true, // prettify URL - } -); - -await request(`/api/users?${query}`); -``` - -
- ## Population The REST API by default does not populate any type of fields, so it will not populate relations, media fields, components, or dynamic zones unless you pass a `populate` parameter to populate various field types. @@ -175,6 +174,32 @@ The population and pagination operators cannot be combined. +
+ + + + +```js +const qs = require('qs'); +const query = qs.stringify( + { + fields: ['title', 'slug'], + populate: { + headerImage: { + fields: ['name', 'url'], + }, + }, + }, + { + encodeValuesOnly: true, // prettify URL + } +); + +await request(`/api/articles?${query}`); +``` + +
+ ```json @@ -202,6 +227,18 @@ The population and pagination operators cannot be combined. + +#### Populate with filtering + +`filters` and `populate` can be combined. + + + + +`GET /api/articles?populate[categories][sort][0]=name%3Aasc&populate[categories][filters][name][$eq]=Cars` + + +
@@ -211,10 +248,14 @@ The population and pagination operators cannot be combined. const qs = require('qs'); const query = qs.stringify( { - fields: ['title', 'slug'], populate: { - headerImage: { - fields: ['name', 'url'], + categories: { + sort: ['name:asc'], + filters: { + name: { + $eq: 'Cars', + }, + }, }, }, }, @@ -228,17 +269,6 @@ await request(`/api/articles?${query}`);
-#### Populate with filtering - -`filters` and `populate` can be combined. - - - - -`GET /api/articles?populate[categories][sort][0]=name%3Aasc&populate[categories][filters][name][$eq]=Cars` - - - ```json @@ -270,33 +300,3 @@ await request(`/api/articles?${query}`); - -
- - - - -```js -const qs = require('qs'); -const query = qs.stringify( - { - populate: { - categories: { - sort: ['name:asc'], - filters: { - name: { - $eq: 'Cars', - }, - }, - }, - }, - }, - { - encodeValuesOnly: true, // prettify URL - } -); - -await request(`/api/articles?${query}`); -``` - -
diff --git a/docusaurus/docs/dev-docs/api/rest/relations.md b/docusaurus/docs/dev-docs/api/rest/relations.md index 9136fbb09a..3f96dd08c6 100644 --- a/docusaurus/docs/dev-docs/api/rest/relations.md +++ b/docusaurus/docs/dev-docs/api/rest/relations.md @@ -10,8 +10,6 @@ tags: - REST API --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Managing relations with API requests Defining relations between content-types (that are designated as entities in the database layers) is connecting entities with each other. diff --git a/docusaurus/docs/dev-docs/api/rest/sort-pagination.md b/docusaurus/docs/dev-docs/api/rest/sort-pagination.md index 55f2e986f6..82d385a543 100644 --- a/docusaurus/docs/dev-docs/api/rest/sort-pagination.md +++ b/docusaurus/docs/dev-docs/api/rest/sort-pagination.md @@ -18,7 +18,6 @@ tags: import QsIntroFull from '/docs/snippets/qs-intro-full.md' import QsForQueryTitle from '/docs/snippets/qs-for-query-title.md' import QsForQueryBody from '/docs/snippets/qs-for-query-body.md' -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' # REST API: Sort & Pagination @@ -42,17 +41,11 @@ The sorting order can be defined with: - `:asc` for ascending order (default order, can be omitted) - or `:desc` for descending order. - - ### Example: Sort using 2 fields You can sort by multiple fields by passing fields in a `sort` array. - - - -
@@ -62,6 +55,24 @@ You can sort by multiple fields by passing fields in a `sort` array. +
+ + + + +```js +const qs = require('qs'); +const query = qs.stringify({ + sort: ['Description', 'Name'], +}, { + encodeValuesOnly: true, // prettify URL +}); + +await request(`/api/restaurants?${query}`); +``` + +
+ ```json @@ -112,6 +123,19 @@ You can sort by multiple fields by passing fields in a `sort` array.
+### Example: Sort using 2 fields and set the order + +Using the `sort` parameter and defining `:asc` or `:desc` on sorted fields, you can get results sorted in a particular order. + +
+ + + + +`GET /api/restaurants?sort[0]=Description:asc&sort[1]=Name:desc` + + +
@@ -120,7 +144,7 @@ You can sort by multiple fields by passing fields in a `sort` array. ```js const qs = require('qs'); const query = qs.stringify({ - sort: ['Description', 'Name'], + sort: ['Description:asc', 'Name:desc'], }, { encodeValuesOnly: true, // prettify URL }); @@ -130,29 +154,6 @@ await request(`/api/restaurants?${query}`);
-
-
- - - - -### Example: Sort using 2 fields and set the order - -Using the `sort` parameter and defining `:asc` or `:desc` on sorted fields, you can get results sorted in a particular order. - - - - - -
- - - - -`GET /api/restaurants?sort[0]=Description:asc&sort[1]=Name:desc` - - - ```json @@ -204,27 +205,6 @@ Using the `sort` parameter and defining `:asc` or `:desc` on sorted fields, you -
- - - - -```js -const qs = require('qs'); -const query = qs.stringify({ - sort: ['Description:asc', 'Name:desc'], -}, { - encodeValuesOnly: true, // prettify URL -}); - -await request(`/api/restaurants?${query}`); -``` - -
- -
-
- ## Pagination Queries can accept `pagination` parameters. Results can be paginated: @@ -252,26 +232,6 @@ To paginate results by page, use the following parameters: `GET /api/articles?pagination[page]=1&pagination[pageSize]=10` - - -```json -{ - "data": [ - // ... - ], - "meta": { - "pagination": { - "page": 1, - "pageSize": 10, - "pageCount": 5, - "total": 48 - } - } -} -``` - - -
@@ -294,6 +254,27 @@ await request(`/api/articles?${query}`);
+ + +```json +{ + "data": [ + // ... + ], + "meta": { + "pagination": { + "page": 1, + "pageSize": 10, + "pageCount": 5, + "total": 48 + } + } +} +``` + + + + ### Pagination by offset To paginate results by offset, use the following parameters: @@ -315,26 +296,6 @@ The default and maximum values for `pagination[limit]` can be [configured in the - - -```json -{ - "data": [ - // ... - ], - "meta": { - "pagination": { - "start": 0, - "limit": 10, - "total": 42 - } - } -} -``` - - - -
@@ -355,3 +316,23 @@ await request(`/api/articles?${query}`); ```
+ + + +```json +{ + "data": [ + // ... + ], + "meta": { + "pagination": { + "start": 0, + "limit": 10, + "total": 42 + } + } +} +``` + + + diff --git a/docusaurus/docs/dev-docs/backend-customization/controllers.md b/docusaurus/docs/dev-docs/backend-customization/controllers.md index d260573a1c..c1ad4bc764 100644 --- a/docusaurus/docs/dev-docs/backend-customization/controllers.md +++ b/docusaurus/docs/dev-docs/backend-customization/controllers.md @@ -245,7 +245,7 @@ Within the Strapi factories the following functions are exposed that can be used These functions automatically inherit the sanitization settings from the model and sanitize the data accordingly based on the content-type schema and any of the content API authentication strategies, such as the Users & Permissions plugin or API tokens. :::warning -Because these methods use the model associated with the current controller, if you query data that is from another model (i.e., doing a find for "menus" within a "restaurant" controller method), you must instead use the `@strapi/utils` tools, such as `sanitize.contentAPI.query` described in [Sanitizing Custom Controllers](#sanitize-validate-custom-controllers), or else the result of your query will be sanitized against the wrong model. +Because these methods use the model associated with the current controller, if you query data that is from another model (i.e., doing a find for "menus" within a "restaurant" controller method), you must instead use tools such as `strapi.contentAPI.sanitize.query` described in [Sanitizing Custom Controllers](#sanitize-validate-custom-controllers), or else the result of your query will be sanitized against the wrong model. ::: @@ -291,15 +291,15 @@ export default factories.createCoreController('api::restaurant.restaurant', ({ s #### Sanitization and validation when building custom controllers {#sanitize-validate-custom-controllers} -Within custom controllers, there are 5 primary functions exposed via the `@strapi/utils` package that can be used for sanitization and validation: +Within custom controllers, there are several primary functions exposed via the global `strapi` namespace that can be used for sanitization and validation: | Function Name | Parameters | Description | |------------------------------|--------------------|---------------------------------------------------------| -| `sanitize.contentAPI.input` | `data`, `schema`, `auth` | Sanitizes the request input including non-writable fields, removing restricted relations, and other nested "visitors" added by plugins | -| `sanitize.contentAPI.output` | `data`, `schema`, `auth` | Sanitizes the response output including restricted relations, private fields, passwords, and other nested "visitors" added by plugins | -| `sanitize.contentAPI.query` | `ctx.query`, `schema`, `auth` | Sanitizes the request query including filters, sort, fields, and populate | -| `validate.contentAPI.query` | `ctx.query`, `schema`, `auth` | Validates the request query including filters, sort, fields (currently not populate) | -| `validate.contentAPI.input` | `data`, `schema`, `auth` | (EXPERIMENTAL) Validates the request input including non-writable fields, removing restricted relations, and other nested "visitors" added by plugins | +| `strapi.contentAPI.sanitize.input` | `data`, `schema`, `auth` | Sanitizes the request input including non-writable fields, removing restricted relations, and other nested "visitors" added by plugins | +| `strapi.contentAPI.sanitize.output` | `data`, `schema`, `auth` | Sanitizes the response output including restricted relations, private fields, passwords, and other nested "visitors" added by plugins | +| `strapi.contentAPI.sanitize.query` | `ctx.query`, `schema`, `auth` | Sanitizes the request query including filters, sort, fields, and populate | +| `strapi.contentAPI.validate.query` | `ctx.query`, `schema`, `auth` | Validates the request query including filters, sort, fields (currently not populate) | +| `strapi.contentAPI.validate.input` | `data`, `schema`, `auth` | (EXPERIMENTAL) Validates the request input including non-writable fields, removing restricted relations, and other nested "visitors" added by plugins | :::note Depending on the complexity of your custom controllers, you may need additional sanitization that Strapi cannot currently account for, especially when combining the data from multiple sources. @@ -310,17 +310,17 @@ Depending on the complexity of your custom controllers, you may need additional ```js title="./src/api/restaurant/controllers/restaurant.js" -const { sanitize, validate } = require('@strapi/utils'); +const { sanitize, validate } = strapi.contentApi; module.exports = { async findCustom(ctx) { const contentType = strapi.contentType('api::test.test'); - await validate.contentAPI.query(ctx.query, contentType, { auth: ctx.state.auth }); - const sanitizedQueryParams = await sanitize.contentAPI.query(ctx.query, contentType, { auth: ctx.state.auth }); + await validate.query(ctx.query, contentType, { auth: ctx.state.auth }); + const sanitizedQueryParams = await sanitize.query(ctx.query, contentType, { auth: ctx.state.auth }); const documents = await strapi.documents(contentType.uid).findMany(sanitizedQueryParams); - return await sanitize.contentAPI.output(documents, contentType, { auth: ctx.state.auth }); + return await sanitize.output(documents, contentType, { auth: ctx.state.auth }); } } ``` @@ -331,18 +331,18 @@ module.exports = { ```js title="./src/api/restaurant/controllers/restaurant.ts" -import { sanitize, validate } from '@strapi/utils'; +const { sanitize, validate } = strapi.contentApi; export default { async findCustom(ctx) { const contentType = strapi.contentType('api::test.test'); - await validate.contentAPI.query(ctx.query, contentType, { auth: ctx.state.auth }); - const sanitizedQueryParams = await sanitize.contentAPI.query(ctx.query, contentType, { auth: ctx.state.auth }); + await validate.query(ctx.query, contentType, { auth: ctx.state.auth }); + const sanitizedQueryParams = await sanitize.query(ctx.query, contentType, { auth: ctx.state.auth }); const documents = await strapi.documents(contentType.uid).findMany(sanitizedQueryParams); - return await sanitize.contentAPI.output(documents, contentType, { auth: ctx.state.auth }); + return await sanitize.output(documents, contentType, { auth: ctx.state.auth }); } } ``` diff --git a/docusaurus/docs/dev-docs/backend-customization/examples.md b/docusaurus/docs/dev-docs/backend-customization/examples.md index c506311292..fa2c766034 100644 --- a/docusaurus/docs/dev-docs/backend-customization/examples.md +++ b/docusaurus/docs/dev-docs/backend-customization/examples.md @@ -6,12 +6,8 @@ pagination_prev: dev-docs/backend-customization pagination_next: dev-docs/backend-customization/examples/authentication --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Backend customization: An examples cookbook using FoodAdvisor - - The present section of the documentation is intended for developers who would like to get a deeper understanding of the Strapi back end customization possibilities. The section is a collection of examples that demonstrate how the core components of the back-end server of Strapi can be used in a real-world project. Front-end code that interacts with the back end may also be part of some examples, but displayed in collapsed blocks by default since front-end code examples are not the main focus of this cookbook. diff --git a/docusaurus/docs/dev-docs/backend-customization/examples/authentication.md b/docusaurus/docs/dev-docs/backend-customization/examples/authentication.md index 9026c3056f..3609416b99 100644 --- a/docusaurus/docs/dev-docs/backend-customization/examples/authentication.md +++ b/docusaurus/docs/dev-docs/backend-customization/examples/authentication.md @@ -6,12 +6,8 @@ pagination_prev: dev-docs/backend-customization/examples pagination_next: dev-docs/backend-customization/examples/services-and-controllers --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Examples cookbook: Authentication flow with JWT - - :::prerequisites This page is part of the back end customization examples cookbook. Please ensure you've read its [introduction](/dev-docs/backend-customization/examples). ::: diff --git a/docusaurus/docs/dev-docs/backend-customization/examples/middlewares.md b/docusaurus/docs/dev-docs/backend-customization/examples/middlewares.md index 313b1a03e5..9f25c97918 100644 --- a/docusaurus/docs/dev-docs/backend-customization/examples/middlewares.md +++ b/docusaurus/docs/dev-docs/backend-customization/examples/middlewares.md @@ -5,12 +5,8 @@ displayed_sidebar: devDocsSidebar pagination_prev: dev-docs/backend-customization/examples/routes --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Examples cookbook: Custom global middlewares - - :::prerequisites This page is part of the back end customization examples cookbook. Please ensure you've read its [introduction](/dev-docs/backend-customization/examples). ::: diff --git a/docusaurus/docs/dev-docs/backend-customization/examples/policies.md b/docusaurus/docs/dev-docs/backend-customization/examples/policies.md index a6339b861c..dfbf390bfc 100644 --- a/docusaurus/docs/dev-docs/backend-customization/examples/policies.md +++ b/docusaurus/docs/dev-docs/backend-customization/examples/policies.md @@ -6,12 +6,8 @@ pagination_prev: dev-docs/backend-customization/examples/services-and-controller pagination_next: dev-docs/backend-customization/examples/routes --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Examples cookbook: Custom policies - - :::prerequisites This page is part of the back end customization examples cookbook. Please ensure you've read its [introduction](/dev-docs/backend-customization/examples). ::: diff --git a/docusaurus/docs/dev-docs/backend-customization/examples/routes.md b/docusaurus/docs/dev-docs/backend-customization/examples/routes.md index dc82df162e..b4239e6798 100644 --- a/docusaurus/docs/dev-docs/backend-customization/examples/routes.md +++ b/docusaurus/docs/dev-docs/backend-customization/examples/routes.md @@ -6,12 +6,8 @@ pagination_prev: dev-docs/backend-customization/examples/policies pagination_next: dev-docs/backend-customization/examples/middlewares --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Examples cookbook: Custom routes - - :::prerequisites This page is part of the back end customization examples cookbook. Please ensure you've read its [introduction](/dev-docs/backend-customization/examples). ::: diff --git a/docusaurus/docs/dev-docs/backend-customization/examples/services-and-controllers.md b/docusaurus/docs/dev-docs/backend-customization/examples/services-and-controllers.md index 831703309a..0907552052 100644 --- a/docusaurus/docs/dev-docs/backend-customization/examples/services-and-controllers.md +++ b/docusaurus/docs/dev-docs/backend-customization/examples/services-and-controllers.md @@ -15,12 +15,8 @@ tags: - services --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Examples cookbook: Custom services and controllers - - :::prerequisites This page is part of the back end customization examples cookbook. Please ensure you've read its [introduction](/dev-docs/backend-customization/examples). ::: diff --git a/docusaurus/docs/dev-docs/backend-customization/webhooks.md b/docusaurus/docs/dev-docs/backend-customization/webhooks.md index 14880c7521..be40221ec7 100644 --- a/docusaurus/docs/dev-docs/backend-customization/webhooks.md +++ b/docusaurus/docs/dev-docs/backend-customization/webhooks.md @@ -13,12 +13,8 @@ tags: - webhooks --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Webhooks - - Webhook is a construct used by an application to notify other applications that an event occurred. More precisely, webhook is a user-defined HTTP callback. Using a webhook is a good way to tell third party providers to start some processing (CI, build, deployment ...). The way a webhook works is by delivering information to a receiving application through HTTP requests (typically POST requests). diff --git a/docusaurus/docs/dev-docs/cli.md b/docusaurus/docs/dev-docs/cli.md index 7a1097b314..f4b799a8db 100644 --- a/docusaurus/docs/dev-docs/cli.md +++ b/docusaurus/docs/dev-docs/cli.md @@ -13,12 +13,8 @@ tags: - strapi report --- -import NotV5 from '/docs/snippets/\_not-updated-to-v5.md' - # Command Line Interface (CLI) - - Strapi comes with a full featured Command Line Interface (CLI) which lets you scaffold and manage your project in seconds. The CLI works with both the `yarn` and `npm` package managers. :::caution diff --git a/docusaurus/docs/dev-docs/configurations/admin-panel.md b/docusaurus/docs/dev-docs/configurations/admin-panel.md index dfc4a6f36c..2e224b86b5 100644 --- a/docusaurus/docs/dev-docs/configurations/admin-panel.md +++ b/docusaurus/docs/dev-docs/configurations/admin-panel.md @@ -13,12 +13,8 @@ tags: - password --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Admin panel configuration - - The `./config/admin.js` is used to define admin panel configuration for the Strapi application. ## Available options diff --git a/docusaurus/docs/dev-docs/configurations/api-tokens.md b/docusaurus/docs/dev-docs/configurations/api-tokens.md index cc1c2d3498..8a489a832d 100644 --- a/docusaurus/docs/dev-docs/configurations/api-tokens.md +++ b/docusaurus/docs/dev-docs/configurations/api-tokens.md @@ -12,12 +12,8 @@ tags: - REST API --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # API tokens - - Authentication strategies in Strapi can either be based on the use of the [Users & Permissions plugin](/user-docs/users-roles-permissions) or on the built-in API token feature. Using API tokens allows executing a request on [REST API](/dev-docs/api/rest) or [GraphQL API](/dev-docs/api/graphql) endpoints as an authenticated user. diff --git a/docusaurus/docs/dev-docs/configurations/api.md b/docusaurus/docs/dev-docs/configurations/api.md index a44d953514..5cd7f1a0f7 100644 --- a/docusaurus/docs/dev-docs/configurations/api.md +++ b/docusaurus/docs/dev-docs/configurations/api.md @@ -8,12 +8,8 @@ tags: - REST API --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # API configuration - - General settings for API calls can be set in the `./config/api.js` file: | Property | Description | Type | Default | diff --git a/docusaurus/docs/dev-docs/configurations/cron.md b/docusaurus/docs/dev-docs/configurations/cron.md index f01c73a3fd..3ef0e3af29 100644 --- a/docusaurus/docs/dev-docs/configurations/cron.md +++ b/docusaurus/docs/dev-docs/configurations/cron.md @@ -8,12 +8,8 @@ tags: - cron job --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Cron jobs - - :::prerequisites The `cron.enabled` configuration option should be set to `true` in the `./config/server.js` (or `./config/server.ts` for TypeScript projects) [file](/dev-docs/configurations/server). ::: diff --git a/docusaurus/docs/dev-docs/configurations/database.md b/docusaurus/docs/dev-docs/configurations/database.md index e39605e704..708018b844 100644 --- a/docusaurus/docs/dev-docs/configurations/database.md +++ b/docusaurus/docs/dev-docs/configurations/database.md @@ -38,7 +38,7 @@ The `/config/database.js|ts` file accepts 2 main configuration objects: | Parameter | Description | Type | Default | |----------------------------------------------------------|-------------------------------------------------------------------------------------------------------|-----------|---------| | `client` | Database client to create the connection.
Accepts the following values:
  • `sqlite` for SQLite databases
  • `postgres` for PostgreSQL databases
  • `mysql` for MySQL databases
| `String` | - | -| `connection` | Database [connection information](#connection-parameters) | `Object` | - | +| `connection` | Database [connection information](#connection-parameters) | `Knex.Config object
Knex.Config Function (experimental)` | - | | `debug` | Show database exchanges and errors. | `Boolean` | `false` | | `useNullAsDefault`

_Optional, only for SQLite_ | Use `NULL` as a default value | `Boolean` | `true` | | `pool`

_Optional_ | [Database pooling options](#database-pooling-options) | `Object` | - | @@ -98,10 +98,15 @@ When using Docker, change the pool `min` value to `0` as Docker will kill any id The `settings` object found in `./config/database.js` (or `./config/database.ts` for TypeScript) is used to configure Strapi-specific database settings and accepts the following parameters: -| Parameter | Description | Type | Default | -| ---------------- | --------------------------------------------------------------- | --------- | ------- | -| `forceMigration` | Enable or disable the forced database migration. | `Boolean` | `true` | -| `runMigrations` | Enable or disable database migrations from running on start up. | `Boolean` | `true` | +| Parameter | Description | Type | Default | +| ---------------- | --------------------------------------------------------------- | --------- | ------- | +| `forceMigration` | Enable or disable the forced database migration. | `Boolean` | `true` | +| `runMigrations` | Enable or disable database migrations from running on start up. | `Boolean` | `true` | +| `useTypescriptMigrations` | Look for migrations in the build dir instead of the src dir | `Boolean` | `false` | + +:::note +When using `useTypescriptMigrations` you can continue to use existing JavaScript migrations by setting `compilerOptions { allowJs: true }` in your tsconfig file. +::: diff --git a/docusaurus/docs/dev-docs/configurations/environment.md b/docusaurus/docs/dev-docs/configurations/environment.md index 4e4a958aab..23dcfd0954 100644 --- a/docusaurus/docs/dev-docs/configurations/environment.md +++ b/docusaurus/docs/dev-docs/configurations/environment.md @@ -8,12 +8,8 @@ tags: - environment --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Environment configuration and variables - - Strapi provides specific environment variable names. Defining them in an environment file (e.g., `.env`) will make these variables and their values available in your code. :::tip diff --git a/docusaurus/docs/dev-docs/configurations/guides/access-cast-environment-variables.md b/docusaurus/docs/dev-docs/configurations/guides/access-cast-environment-variables.md index 37c4008bd6..412f8c2f1f 100644 --- a/docusaurus/docs/dev-docs/configurations/guides/access-cast-environment-variables.md +++ b/docusaurus/docs/dev-docs/configurations/guides/access-cast-environment-variables.md @@ -10,12 +10,8 @@ tags: - environment --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # How to access and cast environment variables - - In most use cases there will be different configurations between environments (e.g. database credentials). Instead of writing those credentials into configuration files, variables can be defined in a `.env` file at the root of the application: diff --git a/docusaurus/docs/dev-docs/configurations/guides/public-assets.md b/docusaurus/docs/dev-docs/configurations/guides/public-assets.md index b7944fc176..34ad09bb7b 100644 --- a/docusaurus/docs/dev-docs/configurations/guides/public-assets.md +++ b/docusaurus/docs/dev-docs/configurations/guides/public-assets.md @@ -10,12 +10,8 @@ tags: - public assets --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # How to use public assets with Strapi - - Public assets are static files (e.g. images, video, CSS files, etc.) that you want to make accessible to the outside world. Because an API may need to serve static assets, every new Strapi project includes by default a folder named `/public`. Any file located in this directory is accessible if the request's path doesn't match any other defined route and if it matches a public file name (e.g. an image named `company-logo.png` in `./public/` is accessible through `/company-logo.png` URL). diff --git a/docusaurus/docs/dev-docs/configurations/guides/rbac.md b/docusaurus/docs/dev-docs/configurations/guides/rbac.md index 4751b75646..b44618d816 100644 --- a/docusaurus/docs/dev-docs/configurations/guides/rbac.md +++ b/docusaurus/docs/dev-docs/configurations/guides/rbac.md @@ -13,12 +13,8 @@ tags: - Users, Roles & Permissions --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # How to create custom conditions for Role-Based Access Control (RBAC) - - Role-Based Access Control (RBAC) is an approach to restricting access to some users. In a Strapi application, users of the admin panel are administrators. Their roles and permissions are [configured in the admin panel](/user-docs/users-roles-permissions/configuring-administrator-roles). ## Declaring new conditions diff --git a/docusaurus/docs/dev-docs/configurations/plugins.md b/docusaurus/docs/dev-docs/configurations/plugins.md index 41f30f7278..75b8e5d045 100644 --- a/docusaurus/docs/dev-docs/configurations/plugins.md +++ b/docusaurus/docs/dev-docs/configurations/plugins.md @@ -14,12 +14,8 @@ tags: --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Plugins configuration - - Plugin configurations are stored in `/config/plugins.js|ts` (see [project structure](/dev-docs/project-structure)). Each plugin can be configured with the following available parameters: | Parameter | Description | Type | @@ -111,7 +107,7 @@ The [GraphQL plugin](/dev-docs/plugins/graphql) has the following specific confi | `maxLimit` | Maximum value for [the `pagination[limit]` parameter](/dev-docs/api/graphql#pagination-by-offset) used in API calls | Integer | `-1` | | `playgroundAlways` | Whether the playground should be publicly exposed.

Enabled by default in if `NODE_ENV` is set to `development`. | Boolean | `false` | | `shadowCRUD` | Whether type definitions for queries, mutations and resolvers based on models should be created automatically (see [Shadow CRUD documentation](/dev-docs/plugins/graphql#shadow-crud)). | Boolean | `true` | -| `v4ComptabilityMode` | Enables the retro-compatibility with the Strapi v4 format (see more details in the [breaking change entry](/dev-docs/migration/v4-to-v5/breaking-changes/graphql-api-updated) | Boolean | `false` | +| `v4CompatibilityMode` | Enables the retro-compatibility with the Strapi v4 format (see more details in the [breaking change entry](/dev-docs/migration/v4-to-v5/breaking-changes/graphql-api-updated) | Boolean | `false` | **Example custom configuration**: diff --git a/docusaurus/docs/dev-docs/configurations/server.md b/docusaurus/docs/dev-docs/configurations/server.md index bc9e3425cf..59394424af 100644 --- a/docusaurus/docs/dev-docs/configurations/server.md +++ b/docusaurus/docs/dev-docs/configurations/server.md @@ -12,12 +12,8 @@ tags: - port --- -import NotV5 from '/docs/snippets/\_not-updated-to-v5.md' - # Server configuration - - The `./config/server.js` file is used to define the server configuration for a Strapi application. :::caution diff --git a/docusaurus/docs/dev-docs/configurations/sso-providers/auth0.md b/docusaurus/docs/dev-docs/configurations/sso-providers/auth0.md new file mode 100644 index 0000000000..4293e8d958 --- /dev/null +++ b/docusaurus/docs/dev-docs/configurations/sso-providers/auth0.md @@ -0,0 +1,131 @@ +--- +title: Auth0 - Admin SSO Provider +description: Steps to configure Auth0 as a Strapi Admin SSO Provider +sidebar_label: Auth0 +displayed_sidebar: devDocsConfigSidebar +tags: +- auth0 +- additional configuration +- admin panel +- configuration +- Enterprise feature +- SSO +--- + +import SSOServerConfig from '/docs/snippets/configuration-sso-server.md' +import SSOAdminConfig from '/docs/snippets/configuration-sso-admin.md' +import SSOMiddlewaresConfig from '/docs/snippets/configuration-sso-middlewares.md' + +:::prerequisites + +- [Properly configure Strapi for SSO](#required-configuration-before-setting-up-sso) +- Create your REPLACEME OAuth2 app by following the steps in the [TODO](https://TODO). +- Gather the required information to set as environment variables in your Strapi project: + - // TODO + +::: + +## Required configuration before setting up SSO + +### Server Configuration + + + +### Admin Configuration + + + +### Middlewares Configuration + + + +## Provider Specific Notes + +### Scopes + +The TODO OAuth2 provider requires the following scopes, however additional scopes can be added as needed depending on your use case and the data you need returned: + +- TODO + +### Profile Data + +Data returned from the provider is dependent on how your TODO OAuth2 application is configured. The example below assumes that the TODO OAuth2 application is configured to return the user's email, first name, and last name. Fields returned by the provider can change based on the scopes requested and the user's TODO account settings. + +If you aren't sure what data is being returned by the provider, you can log the `profile` object in the `createStrategy` function to see what data is available as seen in the following example. + +
+ Configuration Example with Logging + +```js +// TODO +``` + +
+ +### Redirect URL/URI + +The redirect URL/URI will be dependent on your provider configuration however in most cases should combine your application's public URL and the provider's callback URL. The example below shows how to combine the public URL with the provider's callback URL. + +```js +callbackURL: + env('PUBLIC_URL', "https://api.example.com") + + strapi.admin.services.passport.getStrategyCallbackURL("TODO"), +``` + +In this example the redirect URL/URI used by the provider will be `https://api.example.com/admin/connect/TODO`. + +This is broken down as follows: + +- `https://api.example.com` is the public URL of your Strapi application +- `/admin/connect` is the general path for SSO callbacks in Strapi +- `/TODO` is the specific provider UID for TODO + +## Strapi Configuration + +Using: // TODO + +### Install the Provider Package + + + + + +```sh +// TODO +``` + + + + + +```sh +// TODO +``` + + + + + +### Adding the Provider to Strapi + + + + + +```js title="./config/admin.js" + +// TODO +``` + + + + + +```ts title="./config/admin.ts" + +// TODO +``` + + + + diff --git a/docusaurus/docs/dev-docs/configurations/sso-providers/discord.md b/docusaurus/docs/dev-docs/configurations/sso-providers/discord.md new file mode 100644 index 0000000000..e4368e0787 --- /dev/null +++ b/docusaurus/docs/dev-docs/configurations/sso-providers/discord.md @@ -0,0 +1,206 @@ +--- +title: Discord - Admin SSO Provider +description: Steps to configure Discord as a Strapi Admin SSO Provider +sidebar_label: Discord +displayed_sidebar: devDocsConfigSidebar +tags: +- discord +- additional configuration +- admin panel +- configuration +- Enterprise feature +- SSO +--- + +import SSOServerConfig from '/docs/snippets/configuration-sso-server.md' +import SSOAdminConfig from '/docs/snippets/configuration-sso-admin.md' +import SSOMiddlewaresConfig from '/docs/snippets/configuration-sso-middlewares.md' + +:::prerequisites + +- [Properly configure Strapi for SSO](#required-configuration-before-setting-up-sso) +- Create your Discord OAuth2 app by following the steps in the [Discord Developer Console](https://discord.com/developers/docs/topics/oauth2). +- Gather the required information to set as environment variables in your Strapi project: + - DISCORD_CLIENT_ID + - DISCORD_SECRET + +::: + +## Required configuration before setting up SSO + +### Server Configuration + + + +### Admin Configuration + + + +### Middlewares Configuration + + + +## Provider Specific Notes + +### Scopes + +The Discord OAuth2 provider requires the following scopes, however additional scopes can be added as needed depending on your use case and the data you need returned: + +- [`identify`](https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes) +- [`email`](https://discord.com/developers/docs/topics/oauth2#shared-resources-oauth2-scopes) + +### Profile Data + +Data returned from the provider is dependent on how your Discord OAuth2 application is configured. The example below assumes that the Discord OAuth2 application is configured to return the user's email and username. Fields returned by the provider can change based on the scopes requested and the user's Discord account settings. + +If you aren't sure what data is being returned by the provider, you can log the `profile` object in the `createStrategy` function to see what data is available as seen in the following example. + +
+ Configuration Example with Logging + +```js +(accessToken, refreshToken, profile, done) => { + // See what is returned by the provider + console.log(profile); + + done(null, { + email: profile.email, + username: `${profile.username}`, + }); +} +``` + +
+ +### Redirect URL/URI + +The redirect URL/URI will be dependent on your provider configuration however in most cases should combine your application's public URL and the provider's callback URL. The example below shows how to combine the public URL with the provider's callback URL. + +```js +callbackURL: + env('PUBLIC_URL', "https://api.example.com") + + strapi.admin.services.passport.getStrategyCallbackURL("discord"), +``` + +In this example the redirect URL/URI used by the provider will be `https://api.example.com/admin/connect/discord`. + +This is broken down as follows: + +- `https://api.example.com` is the public URL of your Strapi application +- `/admin/connect` is the general path for SSO callbacks in Strapi +- `/discord` is the specific provider UID for Discord + +## Strapi Configuration + +Using: [passport-discord](https://github.com/nicholastay/passport-discord) + +### Install the Provider Package + + + + + +```sh +yarn add passport-discord +``` + + + + + +```sh +npm install --save passport-discord +``` + + + + + +### Adding the Provider to Strapi + + + + + +```js title="./config/admin.js" + +const DiscordStrategy = require("passport-discord"); + +module.exports = ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "discord", + displayName: "Discord", + icon: "https://cdn0.iconfinder.com/data/icons/free-social-media-set/24/discord-512.png", + createStrategy: (strapi) => + new DiscordStrategy( + { + clientID: env("DISCORD_CLIENT_ID"), + clientSecret: env("DISCORD_SECRET"), + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL( + "discord" + ), + scope: ["identify", "email"], + }, + (accessToken, refreshToken, profile, done) => { + done(null, { + email: profile.email, + username: `${profile.username}`, + }); + } + ), + }, + ], + }, +}); +``` + + + + + +```ts title="./config/admin.ts" + +import { Strategy as DiscordStrategy } from "passport-discord"; + + +export default ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "discord", + displayName: "Discord", + icon: "https://cdn0.iconfinder.com/data/icons/free-social-media-set/24/discord-512.png", + createStrategy: (strapi) => + new DiscordStrategy( + { + clientID: env("DISCORD_CLIENT_ID"), + clientSecret: env("DISCORD_SECRET"), + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL( + "discord" + ), + scope: ["identify", "email"], + }, + (accessToken, refreshToken, profile, done) => { + done(null, { + email: profile.email, + username: `${profile.username}`, + }); + } + ), + }, + ], + }, +}); +``` + + + + diff --git a/docusaurus/docs/dev-docs/configurations/sso-providers/entra-id.md b/docusaurus/docs/dev-docs/configurations/sso-providers/entra-id.md new file mode 100644 index 0000000000..584870c9be --- /dev/null +++ b/docusaurus/docs/dev-docs/configurations/sso-providers/entra-id.md @@ -0,0 +1,227 @@ +--- +title: Microsoft Entra ID - Admin SSO Provider +description: Steps to configure Microsoft Entra ID as a Strapi Admin SSO Provider +sidebar_label: Microsoft Entra ID +displayed_sidebar: devDocsConfigSidebar +tags: +- microsoft +- entra id +- azure active directory +- active directory +- additional configuration +- admin panel +- configuration +- Enterprise feature +- SSO +--- + +import SSOServerConfig from '/docs/snippets/configuration-sso-server.md' +import SSOAdminConfig from '/docs/snippets/configuration-sso-admin.md' +import SSOMiddlewaresConfig from '/docs/snippets/configuration-sso-middlewares.md' + +:::prerequisites + +- [Properly configure Strapi for SSO](#required-configuration-before-setting-up-sso) +- Create your EntraID OAuth2 app by following the steps in the [EntraID/Azure Portal](https://learn.microsoft.com/en-us/entra/architecture/auth-oauth2). + - It's important to review the [OAuth application types](https://learn.microsoft.com/en-us/entra/identity-platform/v2-app-types#web-apps) as Strapi only supports "web" applications. +- Gather the required information to set as environment variables in your Strapi project: + - MICROSOFT_CLIENT_ID + - MICROSOFT_CLIENT_SECRET + - MICROSOFT_TENANT_ID + +::: + +## Required configuration before setting up SSO + +### Server Configuration + + + +### Admin Configuration + + + +### Middlewares Configuration + + + +## Provider Specific Notes + +### Scopes + +The EntraID OAuth2 provider requires the following scopes, however additional scopes can be added as needed depending on your use case and the data you need returned: + +- [`user:email`](https://learn.microsoft.com/en-us/entra/identity-platform/scopes-oidc#the-email-scope) + +### Profile Data + +:::warning +It is extremely likely that the below example will not work directly for you as the fields returned by the EntraID instance are extremely subjective to each individual setup. For example some instances will have a `upn` field, others will not and the value type of the `upn` may be different for each instance or even between different users in the same instance. +::: + +Data returned from the provider is dependent on how your EntraID OAuth2 application is configured. The example below assumes that the EntraID OAuth2 application is configured to return the user's email, first name, and last name. Fields returned by the provider can change based on the scopes requested and the user's EntraID account settings. + +If you aren't sure what data is being returned by the provider, you can log the `waadProfile` object in the `createStrategy` function to see what data is available as seen in the following example. + +
+ Configuration Example with Logging + +```js +(accessToken, refreshToken, params, profile, done) => { + let waadProfile = jwt.decode(params.id_token, "", true); + + // See what is returned by the provider + console.log(waadProfile); + + done(null, { + email: waadProfile.email, + username: waadProfile.email, + firstname: waadProfile.given_name, // optional if email and username exist + lastname: waadProfile.family_name, // optional if email and username exist + }); +} +``` + +
+ +### Redirect URL/URI + +The redirect URL/URI will be dependent on your provider configuration however in most cases should combine your application's public URL and the provider's callback URL. The example below shows how to combine the public URL with the provider's callback URL. + +```js +callbackURL: + env('PUBLIC_URL', "https://api.example.com") + + strapi.admin.services.passport.getStrategyCallbackURL("azure_ad_oauth2"), +``` + +In this example the redirect URL/URI used by the provider will be `https://api.example.com/admin/connect/azure_ad_oauth2`. + +This is broken down as follows: + +- `https://api.example.com` is the public URL of your Strapi application +- `/admin/connect` is the general path for SSO callbacks in Strapi +- `/azure_ad_oauth2` is the specific provider UID for Mircosoft Entra ID / Azure Active Directory + +## Strapi Configuration + +Using: [passport-azure-ad-oauth2](https://github.com/auth0/passport-azure-ad-oauth2#readme) + +### Install the Provider Package + + + + + +```sh +yarn add passport-azure-ad-oauth2 jsonwebtoken +``` + + + + + +```sh +npm install --save passport-azure-ad-oauth2 jsonwebtoken +``` + + + + + +### Adding the Provider to Strapi + + + + + +```js title="./config/admin.js" + +const AzureAdOAuth2Strategy = require("passport-azure-ad-oauth2"); +const jwt = require("jsonwebtoken"); + +module.exports = ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "azure_ad_oauth2", + displayName: "Microsoft", + icon: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Microsoft_logo_%282012%29.svg/320px-Microsoft_logo_%282012%29.svg.png", + createStrategy: (strapi) => + new AzureAdOAuth2Strategy( + { + clientID: env("MICROSOFT_CLIENT_ID", ""), + clientSecret: env("MICROSOFT_CLIENT_SECRET", ""), + scope: ["user:email"], + tenant: env("MICROSOFT_TENANT_ID", ""), + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL( + "azure_ad_oauth2" + ), + }, + (accessToken, refreshToken, params, profile, done) => { + let waadProfile = jwt.decode(params.id_token, "", true); + done(null, { + email: waadProfile.email, + username: waadProfile.email, + firstname: waadProfile.given_name, // optional if email and username exist + lastname: waadProfile.family_name, // optional if email and username exist + }); + } + ), + }, + ], + }, +}); +``` + + + + + +```ts title="./config/admin.ts" + +import { Strategy as AzureAdOAuth2Strategy} from "passport-azure-ad-oauth2"; +import jwt from "jsonwebtoken"; + +export default ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "azure_ad_oauth2", + displayName: "Microsoft", + icon: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Microsoft_logo_%282012%29.svg/320px-Microsoft_logo_%282012%29.svg.png", + createStrategy: (strapi) => + new AzureAdOAuth2Strategy( + { + clientID: env("MICROSOFT_CLIENT_ID", ""), + clientSecret: env("MICROSOFT_CLIENT_SECRET", ""), + scope: ["user:email"], + tenant: env("MICROSOFT_TENANT_ID", ""), + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL( + "azure_ad_oauth2" + ), + }, + (accessToken, refreshToken, params, profile, done) => { + let waadProfile = jwt.decode(params.id_token, "", true); + done(null, { + email: waadProfile.email, + username: waadProfile.email, + firstname: waadProfile.given_name, // optional if email and username exist + lastname: waadProfile.family_name, // optional if email and username exist + }); + } + ), + }, + ], + }, +}); +``` + + + + diff --git a/docusaurus/docs/dev-docs/configurations/sso-providers/github.md b/docusaurus/docs/dev-docs/configurations/sso-providers/github.md new file mode 100644 index 0000000000..23b6e21a8b --- /dev/null +++ b/docusaurus/docs/dev-docs/configurations/sso-providers/github.md @@ -0,0 +1,203 @@ +--- +title: GitHub - Admin SSO Provider +description: Steps to configure GitHub as a Strapi Admin SSO Provider +sidebar_label: GitHub +displayed_sidebar: devDocsConfigSidebar +tags: +- github +- additional configuration +- admin panel +- configuration +- Enterprise feature +- SSO +--- + +import SSOServerConfig from '/docs/snippets/configuration-sso-server.md' +import SSOAdminConfig from '/docs/snippets/configuration-sso-admin.md' +import SSOMiddlewaresConfig from '/docs/snippets/configuration-sso-middlewares.md' + +:::prerequisites + +- [Properly configure Strapi for SSO](#required-configuration-before-setting-up-sso) +- Create your GitHub OAuth2 application by following the steps in the [GitHub Developer Settings](https://docs.github.com/en/apps/oauth-apps/building-oauth-apps/creating-an-oauth-app). +- Gather the required information to set as environment variables in your Strapi project: + - GITHUB_CLIENT_ID + - GITHUB_CLIENT_SECRET + +::: + +## Required configuration before setting up SSO + +### Server Configuration + + + +### Admin Configuration + + + +### Middlewares Configuration + + + +## Provider Specific Notes + +### Scopes + +The GitHub OAuth2 provider requires the following scopes, however additional scopes can be added as needed depending on your use case and the data you need returned: + +- `user:email` + +### Profile Data + +Data returned from the provider is dependent on how your GitHub OAuth2 application is configured. The example below assumes that the GitHub OAuth2 application is configured to return the user's email and username. Fields returned by the provider can change based on the scopes requested and the user's GitHub account settings. + +If you aren't sure what data is being returned by the provider, you can log the `profile` object in the `createStrategy` function to see what data is available as seen in the following example. + +
+ Configuration Example with Logging + +```js +(request, accessToken, refreshToken, profile, done) => { + // See what is returned by the provider + console.log(profile); + + done(null, { + // Map the data returned by the provider to the Strapi user object + email: profile.emails[0].value, + username: profile.username, + }); +} +``` + +
+ +### Redirect URL/URI + +The redirect URL/URI will be dependent on your provider configuration however in most cases should combine your application's public URL and the provider's callback URL. The example below shows how to combine the public URL with the provider's callback URL. + +```js +callbackURL: + env('PUBLIC_URL', "https://api.example.com") + + strapi.admin.services.passport.getStrategyCallbackURL("github"), +``` + +In this example the redirect URL/URI used by the provider will be `https://api.example.com/admin/connect/github`. + +This is broken down as follows: + +- `https://api.example.com` is the public URL of your Strapi application +- `/admin/connect` is the general path for SSO callbacks in Strapi +- `/github` is the specific provider UID for GitHub + +## Strapi Configuration + +Using: [passport-github](https://github.com/cfsghost/passport-github) + +### Install the Provider Package + + + + + +```sh +yarn add passport-github2 +``` + + + + + +```sh +npm install --save passport-github2 +``` + + + + + +### Adding the Provider to Strapi + + + + + +```js title="./config/admin.js" + +const GithubStrategy = require("passport-github2"); + +module.exports = ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "github", + displayName: "Github", + icon: "https://cdn1.iconfinder.com/data/icons/logotypes/32/github-512.png", + createStrategy: (strapi) => + new GithubStrategy( + { + clientID: env("GITHUB_CLIENT_ID"), + clientSecret: env("GITHUB_CLIENT_SECRET"), + scope: ["user:email"], + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL("github"), + }, + (accessToken, refreshToken, profile, done) => { + done(null, { + email: profile.emails[0].value, + username: profile.username, + }); + } + ), + }, + ], + }, +}); + +``` + + + + + +```ts title="./config/admin.ts" + +import { Strategy as GithubStrategy } from "passport-github2"; + +export default ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "github", + displayName: "Github", + icon: "https://cdn1.iconfinder.com/data/icons/logotypes/32/github-512.png", + createStrategy: (strapi) => + new GithubStrategy( + { + clientID: env("GITHUB_CLIENT_ID"), + clientSecret: env("GITHUB_CLIENT_SECRET"), + scope: ["user:email"], + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL("github"), + }, + (accessToken, refreshToken, profile, done) => { + done(null, { + email: profile.emails[0].value, + username: profile.username, + }); + } + ), + }, + ], + }, +}); + +``` + + + + diff --git a/docusaurus/docs/dev-docs/configurations/sso-providers/gitlab.md b/docusaurus/docs/dev-docs/configurations/sso-providers/gitlab.md new file mode 100644 index 0000000000..e66a13e97d --- /dev/null +++ b/docusaurus/docs/dev-docs/configurations/sso-providers/gitlab.md @@ -0,0 +1,131 @@ +--- +title: Gitlab - Admin SSO Provider +description: Steps to configure Gitlab as a Strapi Admin SSO Provider +sidebar_label: Gitlab +displayed_sidebar: devDocsConfigSidebar +tags: +- gitlab +- additional configuration +- admin panel +- configuration +- Enterprise feature +- SSO +--- + +import SSOServerConfig from '/docs/snippets/configuration-sso-server.md' +import SSOAdminConfig from '/docs/snippets/configuration-sso-admin.md' +import SSOMiddlewaresConfig from '/docs/snippets/configuration-sso-middlewares.md' + +:::prerequisites + +- [Properly configure Strapi for SSO](#required-configuration-before-setting-up-sso) +- Create your REPLACEME OAuth2 app by following the steps in the [TODO](https://TODO). +- Gather the required information to set as environment variables in your Strapi project: + - // TODO + +::: + +## Required configuration before setting up SSO + +### Server Configuration + + + +### Admin Configuration + + + +### Middlewares Configuration + + + +## Provider Specific Notes + +### Scopes + +The TODO OAuth2 provider requires the following scopes, however additional scopes can be added as needed depending on your use case and the data you need returned: + +- TODO + +### Profile Data + +Data returned from the provider is dependent on how your TODO OAuth2 application is configured. The example below assumes that the TODO OAuth2 application is configured to return the user's email, first name, and last name. Fields returned by the provider can change based on the scopes requested and the user's TODO account settings. + +If you aren't sure what data is being returned by the provider, you can log the `profile` object in the `createStrategy` function to see what data is available as seen in the following example. + +
+ Configuration Example with Logging + +```js +// TODO +``` + +
+ +### Redirect URL/URI + +The redirect URL/URI will be dependent on your provider configuration however in most cases should combine your application's public URL and the provider's callback URL. The example below shows how to combine the public URL with the provider's callback URL. + +```js +callbackURL: + env('PUBLIC_URL', "https://api.example.com") + + strapi.admin.services.passport.getStrategyCallbackURL("TODO"), +``` + +In this example the redirect URL/URI used by the provider will be `https://api.example.com/admin/connect/TODO`. + +This is broken down as follows: + +- `https://api.example.com` is the public URL of your Strapi application +- `/admin/connect` is the general path for SSO callbacks in Strapi +- `/TODO` is the specific provider UID for TODO + +## Strapi Configuration + +Using: // TODO + +### Install the Provider Package + + + + + +```sh +// TODO +``` + + + + + +```sh +// TODO +``` + + + + + +### Adding the Provider to Strapi + + + + + +```js title="./config/admin.js" + +// TODO +``` + + + + + +```ts title="./config/admin.ts" + +// TODO +``` + + + + diff --git a/docusaurus/docs/dev-docs/configurations/sso-providers/google.md b/docusaurus/docs/dev-docs/configurations/sso-providers/google.md new file mode 100644 index 0000000000..e86ec19c9c --- /dev/null +++ b/docusaurus/docs/dev-docs/configurations/sso-providers/google.md @@ -0,0 +1,211 @@ +--- +title: Google - Admin SSO Provider +description: Steps to configure Google as a Strapi Admin SSO Provider +sidebar_label: Google +displayed_sidebar: devDocsConfigSidebar +tags: +- google +- additional configuration +- admin panel +- configuration +- Enterprise feature +- SSO +--- + +import SSOServerConfig from '/docs/snippets/configuration-sso-server.md' +import SSOAdminConfig from '/docs/snippets/configuration-sso-admin.md' +import SSOMiddlewaresConfig from '/docs/snippets/configuration-sso-middlewares.md' + +:::prerequisites + +- [Properly configure Strapi for SSO](#required-configuration-before-setting-up-sso) +- Create your Google OAuth2 app by following the steps in the [Google Console](https://developers.google.com/workspace/guides/create-credentials#oauth-client-id). +- Gather the required information to set as environment variables in your Strapi project: + - GOOGLE_CLIENT_ID + - GOOGLE_CLIENT_SECRET + +::: + +## Required configuration before setting up SSO + +### Server Configuration + + + +### Admin Configuration + + + +### Middlewares Configuration + + + +## Provider Specific Notes + +### Scopes + +The Google OAuth2 provider requires the following scopes, however additional scopes can be added as needed depending on your use case and the data you need returned: + +- `https://www.googleapis.com/auth/userinfo.email` +- `https://www.googleapis.com/auth/userinfo.profile` + +### Profile Data + +Data returned from the provider is dependent on how your Google OAuth2 application is configured. The example below assumes that the Google OAuth2 application is configured to return the user's email, first name, and last name. Fields returned by the provider can change based on the scopes requested and the user's Google account settings. + +If you aren't sure what data is being returned by the provider, you can log the `profile` object in the `createStrategy` function to see what data is available as seen in the following example. + +
+ Configuration Example with Logging + +```js +(request, accessToken, refreshToken, profile, done) => { + // See what is returned by the provider + console.log(profile); + + done(null, { + // Map the data returned by the provider to the Strapi user object + email: profile.email, + firstname: profile.given_name, + lastname: profile.family_name, + }); +} +``` + +
+ +### Redirect URL/URI + +The redirect URL/URI will be dependent on your provider configuration however in most cases should combine your application's public URL and the provider's callback URL. The example below shows how to combine the public URL with the provider's callback URL. + +```js +callbackURL: + env('PUBLIC_URL', "https://api.example.com") + + strapi.admin.services.passport.getStrategyCallbackURL("google"), +``` + +In this example the redirect URL/URI used by the provider will be `https://api.example.com/admin/connect/google`. + +This is broken down as follows: + +- `https://api.example.com` is the public URL of your Strapi application +- `/admin/connect` is the general path for SSO callbacks in Strapi +- `/google` is the specific provider UID for Google + +## Strapi Configuration + +Using: [passport-google-oauth2](https://github.com/mstade/passport-google-oauth2) + +### Install the Provider Package + + + + + +```sh +yarn add passport-google-oauth2 +``` + + + + + +```sh +npm install --save passport-google-oauth2 +``` + + + + + +### Adding the Provider to Strapi + + + + + +```js title="./config/admin.js" + +const GoogleStrategy = require("passport-google-oauth2"); + +module.exports = ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "google", + displayName: "Google", + icon: "https://cdn2.iconfinder.com/data/icons/social-icons-33/128/Google-512.png", + createStrategy: (strapi) => + new GoogleStrategy( + { + clientID: env("GOOGLE_CLIENT_ID"), + clientSecret: env("GOOGLE_CLIENT_SECRET"), + scope: [ + "https://www.googleapis.com/auth/userinfo.email", + "https://www.googleapis.com/auth/userinfo.profile", + ], + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL("google"), + }, + (request, accessToken, refreshToken, profile, done) => { + done(null, { + email: profile.email, + firstname: profile.given_name, + lastname: profile.family_name, + }); + } + ), + }, + ], + }, +}); +``` + + + + + +```ts title="./config/admin.ts" + +import {Strategy as GoogleStrategy } from "passport-google-oauth2"; + +export default ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "google", + displayName: "Google", + icon: "https://cdn2.iconfinder.com/data/icons/social-icons-33/128/Google-512.png", + createStrategy: (strapi) => + new GoogleStrategy( + { + clientID: env("GOOGLE_CLIENT_ID"), + clientSecret: env("GOOGLE_CLIENT_SECRET"), + scope: [ + "https://www.googleapis.com/auth/userinfo.email", + "https://www.googleapis.com/auth/userinfo.profile", + ], + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL("google"), + }, + (request, accessToken, refreshToken, profile, done) => { + done(null, { + email: profile.email, + firstname: profile.given_name, + lastname: profile.family_name, + }); + } + ), + }, + ], + }, +}); +``` + + + + diff --git a/docusaurus/docs/dev-docs/configurations/sso-providers/keycloak.md b/docusaurus/docs/dev-docs/configurations/sso-providers/keycloak.md new file mode 100644 index 0000000000..ce1c9b1820 --- /dev/null +++ b/docusaurus/docs/dev-docs/configurations/sso-providers/keycloak.md @@ -0,0 +1,131 @@ +--- +title: Keycloak - Admin SSO Provider +description: Steps to configure Keycloak as a Strapi Admin SSO Provider +sidebar_label: Keycloak +displayed_sidebar: devDocsConfigSidebar +tags: +- keycloak +- additional configuration +- admin panel +- configuration +- Enterprise feature +- SSO +--- + +import SSOServerConfig from '/docs/snippets/configuration-sso-server.md' +import SSOAdminConfig from '/docs/snippets/configuration-sso-admin.md' +import SSOMiddlewaresConfig from '/docs/snippets/configuration-sso-middlewares.md' + +:::prerequisites + +- [Properly configure Strapi for SSO](#required-configuration-before-setting-up-sso) +- Create your REPLACEME OAuth2 app by following the steps in the [TODO](https://TODO). +- Gather the required information to set as environment variables in your Strapi project: + - // TODO + +::: + +## Required configuration before setting up SSO + +### Server Configuration + + + +### Admin Configuration + + + +### Middlewares Configuration + + + +## Provider Specific Notes + +### Scopes + +The TODO OAuth2 provider requires the following scopes, however additional scopes can be added as needed depending on your use case and the data you need returned: + +- TODO + +### Profile Data + +Data returned from the provider is dependent on how your TODO OAuth2 application is configured. The example below assumes that the TODO OAuth2 application is configured to return the user's email, first name, and last name. Fields returned by the provider can change based on the scopes requested and the user's TODO account settings. + +If you aren't sure what data is being returned by the provider, you can log the `profile` object in the `createStrategy` function to see what data is available as seen in the following example. + +
+ Configuration Example with Logging + +```js +// TODO +``` + +
+ +### Redirect URL/URI + +The redirect URL/URI will be dependent on your provider configuration however in most cases should combine your application's public URL and the provider's callback URL. The example below shows how to combine the public URL with the provider's callback URL. + +```js +callbackURL: + env('PUBLIC_URL', "https://api.example.com") + + strapi.admin.services.passport.getStrategyCallbackURL("TODO"), +``` + +In this example the redirect URL/URI used by the provider will be `https://api.example.com/admin/connect/TODO`. + +This is broken down as follows: + +- `https://api.example.com` is the public URL of your Strapi application +- `/admin/connect` is the general path for SSO callbacks in Strapi +- `/TODO` is the specific provider UID for TODO + +## Strapi Configuration + +Using: // TODO + +### Install the Provider Package + + + + + +```sh +// TODO +``` + + + + + +```sh +// TODO +``` + + + + + +### Adding the Provider to Strapi + + + + + +```js title="./config/admin.js" + +// TODO +``` + + + + + +```ts title="./config/admin.ts" + +// TODO +``` + + + + diff --git a/docusaurus/docs/dev-docs/configurations/sso-providers/okta.md b/docusaurus/docs/dev-docs/configurations/sso-providers/okta.md new file mode 100644 index 0000000000..c179de763e --- /dev/null +++ b/docusaurus/docs/dev-docs/configurations/sso-providers/okta.md @@ -0,0 +1,207 @@ +--- +title: Okta - Admin SSO Provider +description: Steps to configure Okta as a Strapi Admin SSO Provider +sidebar_label: Okta +displayed_sidebar: devDocsConfigSidebar +tags: +- okta +- additional configuration +- admin panel +- configuration +- Enterprise feature +- SSO +--- + +import SSOServerConfig from '/docs/snippets/configuration-sso-server.md' +import SSOAdminConfig from '/docs/snippets/configuration-sso-admin.md' +import SSOMiddlewaresConfig from '/docs/snippets/configuration-sso-middlewares.md' + +:::prerequisites + +- [Properly configure Strapi for SSO](#required-configuration-before-setting-up-sso) +- Create your Okta OAuth2 app by following the steps in the [Okta portal](https://developer.okta.com/docs/guides/implement-oauth-for-okta/main/). +- Gather the required information to set as environment variables in your Strapi project: + - OKTA_CLIENT_ID + - OKTA_CLIENT_SECRET + - OKTA_DOMAIN + +::: + +:::warning +When setting the `OKTA_DOMAIN` environment variable, make sure to include the protocol (e.g. `https://example.okta.com`). If you do not, you will end up in a redirect loop. +::: + +## Required configuration before setting up SSO + +### Server Configuration + + + +### Admin Configuration + + + +### Middlewares Configuration + + + +## Provider Specific Notes + +### Scopes + +The Okta OAuth2 provider requires the following scopes, however additional scopes can be added as needed depending on your use case and the data you need returned: + +- [`openid`](https://developer.okta.com/docs/api/oauth2/) +- [`profile`](https://developer.okta.com/docs/api/oauth2/) +- [`email`](https://developer.okta.com/docs/api/oauth2/) + +### Profile Data + +Data returned from the provider is dependent on how your Okta OAuth2 application is configured. The example below assumes that the Okta OAuth2 application is configured to return the user's email, first name, and last name. Fields returned by the provider can change based on the scopes requested and the user's Okta account settings. + +If you aren't sure what data is being returned by the provider, you can log the `profile` object in the `createStrategy` function to see what data is available as seen in the following example. + +
+ Configuration Example with Logging + +```js +(accessToken, refreshToken, profile, done) => { + // See what is returned by the provider + console.log(profile); + + done(null, { + email: profile.email, + username: profile.username, + }); +} +``` + +
+ +### Redirect URL/URI + +The redirect URL/URI will be dependent on your provider configuration however in most cases should combine your application's public URL and the provider's callback URL. The example below shows how to combine the public URL with the provider's callback URL. + +```js +callbackURL: + env('PUBLIC_URL', "https://api.example.com") + + strapi.admin.services.passport.getStrategyCallbackURL("okta"), +``` + +In this example the redirect URL/URI used by the provider will be `https://api.example.com/admin/connect/okta`. + +This is broken down as follows: + +- `https://api.example.com` is the public URL of your Strapi application +- `/admin/connect` is the general path for SSO callbacks in Strapi +- `/okta` is the specific provider UID for Okta + +## Strapi Configuration + +Using: [passport-okta-oauth20](https://github.com/antoinejaussoin/passport-okta-oauth20/#readme) + +### Install the Provider Package + + + + + +```sh +yarn add passport-okta-oauth20 +``` + + + + + +```sh +npm install --save passport-okta-oauth20 +``` + + + + + +### Adding the Provider to Strapi + + + + + +```js title="./config/admin.js" +const OktaOAuth2Strategy = require("passport-okta-oauth20").Strategy; + +module.exports = ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "okta", + displayName: "Okta", + icon: "https://www.okta.com/sites/default/files/Okta_Logo_BrightBlue_Medium-thumbnail.png", + createStrategy: (strapi) => + new OktaOAuth2Strategy( + { + clientID: env("OKTA_CLIENT_ID"), + clientSecret: env("OKTA_CLIENT_SECRET"), + audience: env("OKTA_DOMAIN"), + scope: ["openid", "email", "profile"], + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL("okta"), + }, + (accessToken, refreshToken, profile, done) => { + done(null, { + email: profile.email, + username: profile.username, + }); + } + ), + }, + ], + }, +}); +``` + + + + + +```ts title="./config/admin.ts" +import { Strategy as OktaOAuth2Strategy } from "passport-okta-oauth20"; + +export default ({ env }) => ({ + auth: { + // ... + providers: [ + { + uid: "okta", + displayName: "Okta", + icon: "https://www.okta.com/sites/default/files/Okta_Logo_BrightBlue_Medium-thumbnail.png", + createStrategy: (strapi) => + new OktaOAuth2Strategy( + { + clientID: env("OKTA_CLIENT_ID"), + clientSecret: env("OKTA_CLIENT_SECRET"), + audience: env("OKTA_DOMAIN"), + scope: ["openid", "email", "profile"], + callbackURL: + env('PUBLIC_URL') + + strapi.admin.services.passport.getStrategyCallbackURL("okta"), + }, + (accessToken, refreshToken, profile, done) => { + done(null, { + email: profile.email, + username: profile.username, + }); + } + ), + }, + ], + }, +}); +``` + + + + diff --git a/docusaurus/docs/dev-docs/configurations/sso.md b/docusaurus/docs/dev-docs/configurations/sso.md index 5aeca782e7..4913158c06 100644 --- a/docusaurus/docs/dev-docs/configurations/sso.md +++ b/docusaurus/docs/dev-docs/configurations/sso.md @@ -2,7 +2,7 @@ title: SSO configuration sidebar_label: Single Sign-On (SSO) displayed_sidebar: devDocsConfigSidebar -description: Strapi's SSO allows you to configure additional sign-in and sign-up methods for your administration panel. It requires an Enterprise Edition with a Gold plan. +description: Strapi's SSO allows you to configure additional sign-in and sign-up methods for your administration panel. It requires an Enterprise Edition. canonicalUrl: https://docs.strapi.io/developer-docs/latest/setup-deployment-guides/configurations/optional/sso.html tags: - additional configuration @@ -12,29 +12,30 @@ tags: - SSO --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Single Sign-On - - Single Sign-On on Strapi allows you to configure additional sign-in and sign-up methods for your administration panel. :::prerequisites - A Strapi application running on version 3.5.0 or higher is required. -- To configure SSO on your application, you will need an EE license with a [Gold plan](https://strapi.io/pricing-self-hosted). +- To configure SSO on your application, you will need an license. - Make sure the SSO feature is [enabled in the admin panel](/user-docs/settings/single-sign-on). -- Make sure Strapi is part of the applications you can access with your provider. For example, with Microsoft (Azure) Active Directory, you must first ask someone with the right permissions to add Strapi to the list of allowed applications. Please refer to your provider(s) documentation to learn more about that. +- You will need to have a working knowledge of JavaScript and Node.js to configure SSO. + ::: :::caution It is currently not possible to associate a unique SSO provider to an email address used for a Strapi account, meaning that the access to a Strapi account cannot be restricted to only one SSO provider. For more information and workarounds to solve this issue, [please refer to the dedicated GitHub issue](https://github.com/strapi/strapi/issues/9466#issuecomment-783587648). ::: -SSO configuration lives in the server configuration of the application, found at `./config/admin.js`. +:::warning +The SSO feature does not currently support cookie authentication, this is something that will be added in a future release but no ETA is available at this time. +::: + +## Accessing the SSO configuration -## Accessing the configuration +The SSO configuration lives in the server configuration of the application, found at `./config/admin.js` or `./config/admin.ts`. The providers' configuration should be written within the `auth.providers` path of the admin panel configuration. @@ -49,8 +50,10 @@ The providers' configuration should be written within the `auth.providers` path module.exports = ({ env }) => ({ // ... auth: { + // ... providers: [], // The providers' configuration lives there }, + // ... }); ``` @@ -63,8 +66,10 @@ module.exports = ({ env }) => ({ export default ({ env }) => ({ // ... auth: { + // ... providers: [], // The providers' configuration lives there }, + // ... }); ``` @@ -87,140 +92,6 @@ A provider's configuration is a JavaScript object built with the following prope The `uid` property is the unique identifier of each strategy and is generally found in the strategy's package. If you are not sure of what it refers to, please contact the maintainer of the strategy. ::: -:::note -By default, Strapi security policy does not allow loading images from external URLs, so provider logos will not show up on the [login screen](/user-docs/intro#accessing-the-admin-panel) of the admin panel unless [a security exception is added](/dev-docs/configurations/middlewares#security). -::: - -
- Example: Security exception for provider logos - - - - -```jsx title="./config/middlewares.js" -module.exports = [ - // ... - { - name: 'strapi::security', - config: { - contentSecurityPolicy: { - useDefaults: true, - directives: { - 'connect-src': ["'self'", 'https:'], - 'img-src': [ - "'self'", - 'data:', - 'blob:', - 'dl.airtable.com', - 'www.okta.com', // Base URL of the provider's logo - ], - 'media-src': [ - "'self'", - 'data:', - 'blob:', - 'dl.airtable.com', - 'www.okta.com', // Base URL of the provider's logo - ], - upgradeInsecureRequests: null, - }, - }, - }, - }, - // ... -] -``` - - - - - -```ts title="./config/middlewares.ts" -export default [ - // ... - { - name: 'strapi::security', - config: { - contentSecurityPolicy: { - useDefaults: true, - directives: { - 'connect-src': ["'self'", 'https:'], - 'img-src': [ - "'self'", - 'data:', - 'blob:', - 'dl.airtable.com', - 'www.okta.com', // Base URL of the provider's logo - ], - 'media-src': [ - "'self'", - 'data:', - 'blob:', - 'dl.airtable.com', - 'www.okta.com', // Base URL of the provider's logo - ], - upgradeInsecureRequests: null, - }, - }, - }, - }, - // ... -] -``` - - - - -
- -:::note -When deploying the admin panel to a different location or on a different subdomain, an additional configuration is required to set the common domain for the cookies. This is required to ensure the cookies are shared across the domains. -::: - -:::caution -Deploying the admin and backend on entirely different unrelated domains is not possible at this time when using SSO. -::: - -
- Example: Setting custom cookie domain - - - - -```jsx title="./config/admin.js" -module.exports = ({ env }) => ({ - auth: { - domain: env("ADMIN_SSO_DOMAIN", ".test.example.com"), - providers: [ - // ... - ], - }, - url: env("ADMIN_URL", "http://admin.test.example.com"), - // ... -}); -``` - - - - - -```ts title="./config/admin.ts" -export default ({ env }) => ({ - auth: { - domain: env("ADMIN_SSO_DOMAIN", ".test.example.com"), - providers: [ - // ... - ], - }, - url: env("ADMIN_URL", "http://admin.test.example.com"), - // ... -}); -``` - - - - -
- ### The `createStrategy` Factory A passport strategy is usually built by instantiating it using 2 parameters: the configuration object, and the verify function. @@ -257,6 +128,10 @@ Adding a new provider means adding a new way for your administrators to log-in. Strapi uses [Passport.js](http://www.passportjs.org/), which enables a large selection of providers. Any valid passport strategy that doesn't need additional custom data should therefore work with Strapi. +:::caution +Strategies are required to have their own "login page" where the user can enter their credentials. If the strategy doesn't have one, it won't work with Strapi's SSO. +::: + :::caution Strategies such as [ldapauth](https://github.com/vesse/passport-ldapauth) don't work out of the box since they require extra data to be sent from the admin panel. If you want to add an LDAP provider to your application, you will need to write a [custom strategy](http://www.passportjs.org/packages/passport-custom/). @@ -270,739 +145,25 @@ To configure a provider, follow the procedure below: 1. Make sure to import your strategy in your admin configuration file, either from an installed package or a local file. 2. You'll need to add a new item to the `auth.providers` array in your admin panel configuration that will match the [format given above](#setting-up-provider-configuration) 3. Restart your application, the provider should appear on your admin login page. - ### Provider configuration examples -#### Google - -Using: [passport-google-oauth2](https://github.com/mstade/passport-google-oauth2) - - - - - -```sh -yarn add passport-google-oauth2 -``` - - - - - -```sh -npm install --save passport-google-oauth2 -``` - - - - - -
- Configuration example for Google: -
-
-
- - - - -```js title="./config/admin.js" - -const GoogleStrategy = require("passport-google-oauth2"); - -module.exports = ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "google", - displayName: "Google", - icon: "https://cdn2.iconfinder.com/data/icons/social-icons-33/128/Google-512.png", - createStrategy: (strapi) => - new GoogleStrategy( - { - clientID: env("GOOGLE_CLIENT_ID"), - clientSecret: env("GOOGLE_CLIENT_SECRET"), - scope: [ - "https://www.googleapis.com/auth/userinfo.email", - "https://www.googleapis.com/auth/userinfo.profile", - ], - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL("google"), - }, - (request, accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.email, - firstname: profile.given_name, - lastname: profile.family_name, - }); - } - ), - }, - ], - }, -}); -``` - - - - - -```ts title="./config/admin.ts" - -import {Strategy as GoogleStrategy } from "passport-google-oauth2"; - -export default ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "google", - displayName: "Google", - icon: "https://cdn2.iconfinder.com/data/icons/social-icons-33/128/Google-512.png", - createStrategy: (strapi) => - new GoogleStrategy( - { - clientID: env("GOOGLE_CLIENT_ID"), - clientSecret: env("GOOGLE_CLIENT_SECRET"), - scope: [ - "https://www.googleapis.com/auth/userinfo.email", - "https://www.googleapis.com/auth/userinfo.profile", - ], - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL("google"), - }, - (request, accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.email, - firstname: profile.given_name, - lastname: profile.family_name, - }); - } - ), - }, - ], - }, -}); -``` - - - - - -
-
-
-
- -#### Github - -Using: [passport-github](https://github.com/cfsghost/passport-github) - - - - - -```sh -yarn add passport-github2 -``` - - - - - -```sh -npm install --save passport-github2 -``` - - - - - -
- Configuration example for Github: -
-
- - - - -```js title="./config/admin.js" - -const GithubStrategy = require("passport-github2"); - -module.exports = ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "github", - displayName: "Github", - icon: "https://cdn1.iconfinder.com/data/icons/logotypes/32/github-512.png", - createStrategy: (strapi) => - new GithubStrategy( - { - clientID: env("GITHUB_CLIENT_ID"), - clientSecret: env("GITHUB_CLIENT_SECRET"), - scope: ["user:email"], - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL("github"), - }, - (accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.emails[0].value, - username: profile.username, - }); - } - ), - }, - ], - }, -}); - -``` - - - - - -```ts title="./config/admin.ts" - -import { Strategy as GithubStrategy } from "passport-github2"; - -export default ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "github", - displayName: "Github", - icon: "https://cdn1.iconfinder.com/data/icons/logotypes/32/github-512.png", - createStrategy: (strapi) => - new GithubStrategy( - { - clientID: env("GITHUB_CLIENT_ID"), - clientSecret: env("GITHUB_CLIENT_SECRET"), - scope: ["user:email"], - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL("github"), - }, - (accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.emails[0].value, - username: profile.username, - }); - } - ), - }, - ], - }, -}); - -``` - - - - -
-
-
-
- -#### Discord - -Using: [passport-discord](https://github.com/nicholastay/passport-discord#readme) - - - - - -```sh -yarn add passport-discord -``` - - - - - -```sh -npm install --save passport-discord -``` - - - - - -
- Configuration example for Discord: -
-
-
- - - - -```jsx title="./config/admin.js" - -const DiscordStrategy = require("passport-discord"); - -module.exports = ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "discord", - displayName: "Discord", - icon: "https://cdn0.iconfinder.com/data/icons/free-social-media-set/24/discord-512.png", - createStrategy: (strapi) => - new DiscordStrategy( - { - clientID: env("DISCORD_CLIENT_ID"), - clientSecret: env("DISCORD_SECRET"), - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL( - "discord" - ), - scope: ["identify", "email"], - }, - (accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.email, - username: `${profile.username}#${profile.discriminator}`, - }); - } - ), - }, - ], - }, -}); -``` - - - - - -```ts title="./config/admin.ts" - -import { Strategy as DiscordStrategy } from "passport-discord"; - - -export default ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "discord", - displayName: "Discord", - icon: "https://cdn0.iconfinder.com/data/icons/free-social-media-set/24/discord-512.png", - createStrategy: (strapi) => - new DiscordStrategy( - { - clientID: env("DISCORD_CLIENT_ID"), - clientSecret: env("DISCORD_SECRET"), - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL( - "discord" - ), - scope: ["identify", "email"], - }, - (accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.email, - username: `${profile.username}#${profile.discriminator}`, - }); - } - ), - }, - ], - }, -}); -``` - - - - -
-
-
-
- -#### Microsoft - -Using: [passport-azure-ad-oauth2](https://github.com/auth0/passport-azure-ad-oauth2#readme) - - - - - -```sh -yarn add passport-azure-ad-oauth2 jsonwebtoken -``` - - - - - -```sh -npm install --save passport-azure-ad-oauth2 jsonwebtoken -``` - - - - - -
- Configuration example for Microsoft: -
-
- - - - -```js title="./config/admin.js" - -const AzureAdOAuth2Strategy = require("passport-azure-ad-oauth2"); -const jwt = require("jsonwebtoken"); - -module.exports = ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "azure_ad_oauth2", - displayName: "Microsoft", - icon: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Microsoft_logo_%282012%29.svg/320px-Microsoft_logo_%282012%29.svg.png", - createStrategy: (strapi) => - new AzureAdOAuth2Strategy( - { - clientID: env("MICROSOFT_CLIENT_ID", ""), - clientSecret: env("MICROSOFT_CLIENT_SECRET", ""), - scope: ["user:email"], - tenant: env("MICROSOFT_TENANT_ID", ""), - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL( - "azure_ad_oauth2" - ), - }, - (accessToken, refreshToken, params, profile, done) => { - let waadProfile = jwt.decode(params.id_token, "", true); - done(null, { - email: waadProfile.email, - username: waadProfile.email, - firstname: waadProfile.given_name, // optional if email and username exist - lastname: waadProfile.family_name, // optional if email and username exist - }); - } - ), - }, - ], - }, -}); -``` - - - - - -```ts title="./config/admin.ts" - -import { Strategy as AzureAdOAuth2Strategy} from "passport-azure-ad-oauth2"; -import jwt from "jsonwebtoken"; - -export default ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "azure_ad_oauth2", - displayName: "Microsoft", - icon: "https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Microsoft_logo_%282012%29.svg/320px-Microsoft_logo_%282012%29.svg.png", - createStrategy: (strapi) => - new AzureAdOAuth2Strategy( - { - clientID: env("MICROSOFT_CLIENT_ID", ""), - clientSecret: env("MICROSOFT_CLIENT_SECRET", ""), - scope: ["user:email"], - tenant: env("MICROSOFT_TENANT_ID", ""), - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL( - "azure_ad_oauth2" - ), - }, - (accessToken, refreshToken, params, profile, done) => { - let waadProfile = jwt.decode(params.id_token, "", true); - done(null, { - email: waadProfile.email, - username: waadProfile.email, - firstname: waadProfile.given_name, // optional if email and username exist - lastname: waadProfile.family_name, // optional if email and username exist - }); - } - ), - }, - ], - }, -}); -``` - - - - -
-
-
-
- -#### Keycloak (OpenID Connect) - -Using: [passport-keycloak-oauth2-oidc](https://www.npmjs.com/package/passport-keycloak-oauth2-oidc) - - - - - -```sh -yarn add passport-keycloak-oauth2-oidc -``` - - - - - -```sh -npm install --save passport-keycloak-oauth2-oidc -``` - - - - - - - -
- Configuration example for Keycloak (OpenID Connect): -
-
- - - - -```js title="./config/admin.js" - -const KeyCloakStrategy = require("passport-keycloak-oauth2-oidc"); - -module.exports = ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "keycloak", - displayName: "Keycloak", - icon: "https://raw.githubusercontent.com/keycloak/keycloak-admin-ui/main/themes/keycloak/logo.svg", - createStrategy: (strapi) => - new KeyCloakStrategy( - { - clientID: env("KEYCLOAK_CLIENT_ID", ""), - realm: env("KEYCLOAK_REALM", ""), - publicClient: env.bool("KEYCLOAK_PUBLIC_CLIENT", false), - clientSecret: env("KEYCLOAK_CLIENT_SECRET", ""), - sslRequired: env("KEYCLOAK_SSL_REQUIRED", "external"), - authServerURL: env("KEYCLOAK_AUTH_SERVER_URL", ""), - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL( - "keycloak" - ), - }, - (accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.email, - username: profile.username, - }); - } - ), - }, - ], - }, -}); -``` - - - - - -```ts title="./config/admin.ts" - -import { Strategy as KeyCloakStrategy } from "passport-keycloak-oauth2-oidc"; - -export default ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "keycloak", - displayName: "Keycloak", - icon: "https://raw.githubusercontent.com/keycloak/keycloak-admin-ui/main/themes/keycloak/logo.svg", - createStrategy: (strapi) => - new KeyCloakStrategy( - { - clientID: env("KEYCLOAK_CLIENT_ID", ""), - realm: env("KEYCLOAK_REALM", ""), - publicClient: env.bool("KEYCLOAK_PUBLIC_CLIENT", false), - clientSecret: env("KEYCLOAK_CLIENT_SECRET", ""), - sslRequired: env("KEYCLOAK_SSL_REQUIRED", "external"), - authServerURL: env("KEYCLOAK_AUTH_SERVER_URL", ""), - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL( - "keycloak" - ), - }, - (accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.email, - username: profile.username, - }); - } - ), - }, - ], - }, -}); -``` - - - - -
-
-
-
- -#### Okta - -Using: [passport-okta-oauth20](https://github.com/antoinejaussoin/passport-okta-oauth20/#readme) - - - - - -```sh -yarn add passport-okta-oauth20 -``` - - - - - -```sh -npm install --save passport-okta-oauth20 -``` - - - - - -:::caution -When setting the `OKTA_DOMAIN` environment variable, make sure to include the protocol (e.g. `https://example.okta.com`). If you do not, you will end up in a redirect loop. -::: - -
- Configuration example for Okta: -
-
- - - - -```js title="./config/admin.js" - -const OktaOAuth2Strategy = require("passport-okta-oauth20").Strategy; - -module.exports = ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "okta", - displayName: "Okta", - icon: "https://www.okta.com/sites/default/files/Okta_Logo_BrightBlue_Medium-thumbnail.png", - createStrategy: (strapi) => - new OktaOAuth2Strategy( - { - clientID: env("OKTA_CLIENT_ID"), - clientSecret: env("OKTA_CLIENT_SECRET"), - audience: env("OKTA_DOMAIN"), - scope: ["openid", "email", "profile"], - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL("okta"), - }, - (accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.email, - username: profile.username, - }); - } - ), - }, - ], - }, -}); -``` - - - - - -```ts title="./config/admin.ts" - -import { Strategy as OktaOAuth2Strategy } from "passport-okta-oauth20"; - -export default ({ env }) => ({ - auth: { - // ... - providers: [ - { - uid: "okta", - displayName: "Okta", - icon: "https://www.okta.com/sites/default/files/Okta_Logo_BrightBlue_Medium-thumbnail.png", - createStrategy: (strapi) => - new OktaOAuth2Strategy( - { - clientID: env("OKTA_CLIENT_ID"), - clientSecret: env("OKTA_CLIENT_SECRET"), - audience: env("OKTA_DOMAIN"), - scope: ["openid", "email", "profile"], - callbackURL: - strapi.admin.services.passport.getStrategyCallbackURL("okta"), - }, - (accessToken, refreshToken, profile, done) => { - done(null, { - email: profile.email, - username: profile.username, - }); - } - ), - }, - ], - }, -}); -``` - - - - -
-
-
-
+| Provider | Package | Configuration | +|--------------------|----------------------------|----------------------------------------------------------------------------| +| Auth0 | `passport-auth0` | [Auth0 configuration](/dev-docs/configurations/sso-providers/auth0) | +| Discord | `passport-discord` | [Discord configuration](/dev-docs/configurations/sso-providers/discord) | +| Microsoft Entra ID | `passport-azure-ad-oauth2` | [Microsoft configuration](/dev-docs/configurations/sso-providers/entra-id) | +| GitHub | `passport-github` | [GitHub configuration](/dev-docs/configurations/sso-providers/github) | +| Gitlab | `passport-gitlab2` | [Gitlab configuration](/dev-docs/configurations/sso-providers/gitlab) | +| Google | `passport-google-oauth20` | [Google configuration](/dev-docs/configurations/sso-providers/google) | +| Keycloak | `passport-keycloak-oauth2` | [Keycloak configuration](/dev-docs/configurations/sso-providers/keycloak) | +| Okta | `passport-okta-oauth20` | [Okta configuration](/dev-docs/configurations/sso-providers/okta) | + + ## Performing advanced customization -### Admin panel URL - -If the administration panel lives on a host/port different from the Strapi server, the admin panel URL needs to be updated: -update the `url` key in the `./config/admin.js` configuration file (see [admin panel customization documentation](/dev-docs/admin-panel-customization#access-url)). - ### Custom Logic In some scenarios, you will want to write additional logic for your connection workflow such as: diff --git a/docusaurus/docs/dev-docs/configurations/typescript.md b/docusaurus/docs/dev-docs/configurations/typescript.md index 6d92fe89b6..11a29450b6 100644 --- a/docusaurus/docs/dev-docs/configurations/typescript.md +++ b/docusaurus/docs/dev-docs/configurations/typescript.md @@ -10,12 +10,8 @@ tags: - typescript --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # TypeScript configuration - - [TypeScript](/dev-docs/typescript)-enabled Strapi projects have a specific project structure and handle TypeScript project configuration through [`tsconfig.json` files](#project-structure-and-typescript-specific-configuration-files). Strapi also has dedicated TypeScript features that are configured [in the `config/typescript.js|ts` file](#strapi-specific-configuration-for-typescript). diff --git a/docusaurus/docs/dev-docs/custom-fields.md b/docusaurus/docs/dev-docs/custom-fields.md index 3f5a6edfe5..48a1071199 100644 --- a/docusaurus/docs/dev-docs/custom-fields.md +++ b/docusaurus/docs/dev-docs/custom-fields.md @@ -13,12 +13,9 @@ tags: --- import CustomFieldRequiresPlugin from '/docs/snippets/custom-field-requires-plugin.md' -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' # Custom fields - - Custom fields extend Strapi’s capabilities by adding new types of fields to content-types and components. Once created or added to Strapi via plugins, custom fields can be used in the Content-Type Builder and Content Manager just like built-in fields. The present documentation is intended for custom field creators: it describes which APIs and functions developers must use to create a new custom field. The [User Guide](/user-docs/plugins/introduction-to-plugins.md#custom-fields) describes how to add and use custom fields from Strapi's admin panel. diff --git a/docusaurus/docs/dev-docs/data-management/export.md b/docusaurus/docs/dev-docs/data-management/export.md index bf672770ad..72ca7f7cd7 100644 --- a/docusaurus/docs/dev-docs/data-management/export.md +++ b/docusaurus/docs/dev-docs/data-management/export.md @@ -15,12 +15,8 @@ tags: - tar.gz.enc file --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Data export - - The `strapi export` command is used to export data from a local Strapi instance. By default, the `strapi export` command exports data as an encrypted and compressed `tar.gz.enc` file which includes: - the project configuration, diff --git a/docusaurus/docs/dev-docs/data-management/import.md b/docusaurus/docs/dev-docs/data-management/import.md index b8232a697a..39d57aec6e 100644 --- a/docusaurus/docs/dev-docs/data-management/import.md +++ b/docusaurus/docs/dev-docs/data-management/import.md @@ -13,12 +13,8 @@ tags: - tar.gz.enc file --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Data import - - The `strapi import` command is used to import data from a file. By default, the `strapi import` command imports data from an encrypted and compressed `tar.gz.enc` file which includes: - the project configuration, diff --git a/docusaurus/docs/dev-docs/data-management/transfer.md b/docusaurus/docs/dev-docs/data-management/transfer.md index 800cbef2aa..23b08e3bcb 100644 --- a/docusaurus/docs/dev-docs/data-management/transfer.md +++ b/docusaurus/docs/dev-docs/data-management/transfer.md @@ -10,12 +10,8 @@ tags: - environment --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Data transfer - - The `strapi transfer` command streams your data from one Strapi instance to another Strapi instance. The `transfer` command uses strict schema matching, meaning your two Strapi instances need to be exact copies of each other except for the contained data. The default `transfer` command transfers your content (entities and relations), files (assets), project configuration, and schemas. The command allows you to transfer data: - from a local Strapi instance to a remote Strapi instance diff --git a/docusaurus/docs/dev-docs/database-migrations.md b/docusaurus/docs/dev-docs/database-migrations.md index f3f3d209cb..39be8e3a6f 100644 --- a/docusaurus/docs/dev-docs/database-migrations.md +++ b/docusaurus/docs/dev-docs/database-migrations.md @@ -3,12 +3,8 @@ title: Database migrations description: Strapi database migrations are ways to modify the database --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Database migrations - - Database migrations exist to run one-time queries against the database, typically to modify the tables structure or the data when upgrading the Strapi application. These migrations are run automatically when the application starts and are executed before the automated schema migrations that Strapi also performs on boot. :::callout 🚧 Experimental feature @@ -109,5 +105,3 @@ module.exports = { ``` - -Footer diff --git a/docusaurus/docs/dev-docs/error-handling.md b/docusaurus/docs/dev-docs/error-handling.md index 256640eb19..0a30a7cdc6 100644 --- a/docusaurus/docs/dev-docs/error-handling.md +++ b/docusaurus/docs/dev-docs/error-handling.md @@ -14,12 +14,8 @@ tags: - strapi-utils --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Error handling - - Strapi is natively handling errors with a standard format. There are 2 use cases for error handling: diff --git a/docusaurus/docs/dev-docs/faq.md b/docusaurus/docs/dev-docs/faq.md index 5bfbc61937..a164684aa8 100644 --- a/docusaurus/docs/dev-docs/faq.md +++ b/docusaurus/docs/dev-docs/faq.md @@ -19,12 +19,8 @@ tags: --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Frequently Asked Questions - - Below are answers and solutions to most common issues that you may experience when working with Strapi. ## Why can't I create or update content-types in production/staging? diff --git a/docusaurus/docs/dev-docs/installation/docker.md b/docusaurus/docs/dev-docs/installation/docker.md index fda1262940..01d3eaf78f 100644 --- a/docusaurus/docs/dev-docs/installation/docker.md +++ b/docusaurus/docs/dev-docs/installation/docker.md @@ -71,7 +71,7 @@ WORKDIR /opt/ COPY package.json yarn.lock ./ RUN yarn global add node-gyp RUN yarn config set network-timeout 600000 -g && yarn install -ENV PATH /opt/node_modules/.bin:$PATH +ENV PATH=/opt/node_modules/.bin:$PATH WORKDIR /opt/app COPY . . @@ -97,7 +97,7 @@ WORKDIR /opt/ COPY package.json package-lock.json ./ RUN npm install -g node-gyp RUN npm config set fetch-retry-maxtimeout 600000 -g && npm install -ENV PATH /opt/node_modules/.bin:$PATH +ENV PATH=/opt/node_modules/.bin:$PATH WORKDIR /opt/app COPY . . @@ -352,7 +352,7 @@ WORKDIR /opt/ COPY package.json yarn.lock ./ RUN yarn global add node-gyp RUN yarn config set network-timeout 600000 -g && yarn install --production -ENV PATH /opt/node_modules/.bin:$PATH +ENV PATH=/opt/node_modules/.bin:$PATH WORKDIR /opt/app COPY . . RUN yarn build @@ -366,7 +366,7 @@ WORKDIR /opt/ COPY --from=build /opt/node_modules ./node_modules WORKDIR /opt/app COPY --from=build /opt/app ./ -ENV PATH /opt/node_modules/.bin:$PATH +ENV PATH=/opt/node_modules/.bin:$PATH RUN chown -R node:node /opt/app USER node @@ -389,7 +389,7 @@ WORKDIR /opt/ COPY package.json package-lock.json ./ RUN npm install -g node-gyp RUN npm config set fetch-retry-maxtimeout 600000 -g && npm install --only=production -ENV PATH /opt/node_modules/.bin:$PATH +ENV PATH=/opt/node_modules/.bin:$PATH WORKDIR /opt/app COPY . . RUN npm run build @@ -403,7 +403,7 @@ WORKDIR /opt/ COPY --from=build /opt/node_modules ./node_modules WORKDIR /opt/app COPY --from=build /opt/app ./ -ENV PATH /opt/node_modules/.bin:$PATH +ENV PATH=/opt/node_modules/.bin:$PATH RUN chown -R node:node /opt/app USER node diff --git a/docusaurus/docs/dev-docs/migration/v4-to-v5/additional-resources/helper-plugin.md b/docusaurus/docs/dev-docs/migration/v4-to-v5/additional-resources/helper-plugin.md index 1aaaae31f0..92747f107f 100644 --- a/docusaurus/docs/dev-docs/migration/v4-to-v5/additional-resources/helper-plugin.md +++ b/docusaurus/docs/dev-docs/migration/v4-to-v5/additional-resources/helper-plugin.md @@ -74,10 +74,10 @@ const MyProtectedPage = () => { import { Page } from '@strapi/strapi/admin'; const MyProtectedPage = () => { - return ( - + + ); }; ``` diff --git a/docusaurus/docs/dev-docs/migration/v4-to-v5/additional-resources/plugins-migration.md b/docusaurus/docs/dev-docs/migration/v4-to-v5/additional-resources/plugins-migration.md index 8d68d9a025..8066b5b07d 100644 --- a/docusaurus/docs/dev-docs/migration/v4-to-v5/additional-resources/plugins-migration.md +++ b/docusaurus/docs/dev-docs/migration/v4-to-v5/additional-resources/plugins-migration.md @@ -25,6 +25,10 @@ Upgrading a Strapi v4 plugin to Strapi 5 consists in: 1. Creating a new empty plugin using the [Plugin SDK](/dev-docs/plugins/development/create-a-plugin). 2. Move your Strapi v4 code to the newly created files in the Strapi 5 [plugin structure](/dev-docs/plugins/development/plugin-structure), also considering the changes summarized in this page. +:::tip Tip: Partly automate the migration +Some parts of the plugin migration can be automated by the CLI upgrade tool through its **codemods** . You can run `npx @strapi/upgrade codemods ls` to list available codemods and `npx @strapi/upgrade codemods run` to run a specific codemod. See the [list of codemods](/dev-docs/migration/v4-to-v5/step-by-step#step-2-run-automated-migrations) and the [reference documentation for the upgrade tool](/dev-docs/upgrade-tool#run-codemods-only) for more details. +::: + Alternatively, you can manually update your Strapi v4 plugin to use the Plugin SDK. The manual steps include: 1. If your code uses a format other than CommonJS, update the `package.json` file and specify the appropriate exports property. diff --git a/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes.md b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes.md index c9fa8363be..1f5ea99f3f 100644 --- a/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes.md +++ b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes.md @@ -93,6 +93,7 @@ You can click on the description of any breaking change in the following tables | [The Entity Service API is deprecated and replaced by the Document Service API](/dev-docs/migration/v4-to-v5/breaking-changes/entity-service-deprecated) | Yes | 👷 Partly | | [`documentId` should be used instead of `id` in API calls](/dev-docs/migration/v4-to-v5/breaking-changes/use-document-id) | Yes | 👷 Partly | | [Database lifecycle hooks are triggered differently based on Document Service API methods](/dev-docs/migration/v4-to-v5/breaking-changes/lifecycle-hooks-document-service) | Yes | No | +| [The `publishedAt` parameter is not supported and replaced by `status`](/dev-docs/migration/v4-to-v5/breaking-changes/publishedat-removed) | Yes | ✅ Yes | | [The `publicationState` parameter is not supported and replaced by `status`](/dev-docs/migration/v4-to-v5/breaking-changes/publication-state-removed) | Yes | ✅ Yes | | [Sorting by id is no longer possible to sort by chronological order](/dev-docs/migration/v4-to-v5/breaking-changes/sort-by-id) | Yes | ✅ Yes | | [There is no `findPage()` method with the Document Service API](/dev-docs/migration/v4-to-v5/breaking-changes/no-find-page-in-document-service) | Yes | No | diff --git a/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/graphql-api-updated.md b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/graphql-api-updated.md index 7e2c537bf4..10ae8f872b 100644 --- a/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/graphql-api-updated.md +++ b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/graphql-api-updated.md @@ -28,7 +28,7 @@ In Strapi 5, the GraphQL API has been updated. It handles the new, flattened res | Topic | Description of the changes | |------------------------------|-----------------------------------------------------------------------------------------------------| -| File upload support |
  • Removed `uploadFile` `uploadFiles` mutations
  • Removed `updateFileInfo` mutation in favor of using the `updateUploadFile` mutation
  • Removed `removeFile` mutation in favor of using the `deleteUploadFile` mutation
  • Removed `folder` queries & mutations
  • Removed `createUploadFile` mutation
| +| File upload support |
  • Removed `upload` `multipleUpload` mutations
  • Removed `updateFileInfo` mutation in favor of using the `updateUploadFile` mutation
  • Removed `removeFile` mutation in favor of using the `deleteUploadFile` mutation
  • Removed `folder` queries & mutations
  • Removed `createUploadFile` mutation
| | Internationalization support | Removed the `createXXLocalization` mutations in favor of being able to update any locale from the main `updateXXX` mutation | | Draft & Publish support | Removed `publicationState` in favor of `status` to align with the new Draft & Publish behavior | | Schema changes |
  • Simplified the basic queries with no `meta`/`pagination`
  • Introduced `Connection` to add pagination
| @@ -39,7 +39,7 @@ For an extensive description of the new Strapi 5 GraphQL API, please refer to th To gradually convert to the new GraphQL API format, follow these steps: -1. Enable v4 compatibility mode with the `v4ComptabilityMode` flag in the configuration of the GraphQL plugin (see [plugins configuration](/dev-docs/configurations/plugins#graphql-configuration)): +1. Enable v4 compatibility mode with the `v4CompatibilityMode` flag in the configuration of the GraphQL plugin (see [plugins configuration](/dev-docs/configurations/plugins#graphql-configuration)): ```graphql { diff --git a/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/new-response-format.md b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/new-response-format.md index af9f7bcbfa..7723b4ef9b 100644 --- a/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/new-response-format.md +++ b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/new-response-format.md @@ -45,7 +45,7 @@ The Content API returns all the attributes of requested content wrapped inside a "title": "Article A" "relation": { "data": { - "id": "clkgylw7d000108lc4rw1bb6s" + "id": "2" "name": "Category A" } } diff --git a/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/publishedat-removed.md b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/publishedat-removed.md new file mode 100644 index 0000000000..1b8fd6d157 --- /dev/null +++ b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/publishedat-removed.md @@ -0,0 +1,67 @@ +--- +title: publishedAt can't be used anymore to define the status +description: In Strapi 5, 'publishedAt' can no longer be used in Content API calls to set the status. The new status parameter can be used and accepts 2 different values, draft and published. +sidebar_label: status instead of publishedAt +displayed_sidebar: devDocsMigrationV5Sidebar +tags: + - breaking changes + - Content API + - GraphQL API + - Document Service API + - Draft & Publish + - upgrade to Strapi 5 +--- + +import Intro from '/docs/snippets/breaking-change-page-intro.md' +import MigrationIntro from '/docs/snippets/breaking-change-page-migration-intro.md' +import YesPlugins from '/docs/snippets/breaking-change-affecting-plugins.md' +import YesCodemods from '/docs/snippets/breaking-change-handled-by-codemod.md' + +# `publishedAt` is removed and replaced by `status` + +In Strapi 5, the [Draft & Publish feature](/user-docs/content-manager/saving-and-publishing-content) has been reworked, and the Content API, including REST, GraphQL, and Document Service APIs accept a new `status` parameter. + + + + + + +## Breaking change description + + + + + +**In Strapi v4** + +`publishedAt` is used in the request body and accepts the following values: + +- `null` sets an entry in draft, +- A date string (e.g., `2021-10-28T16:57:26.352Z`) sets the entry to published status. + + + + + +**In Strapi 5** + +`status` is used as a query parameter and accepts the following values: + +- `draft` sets a in the draft version, +- `published` sets a in the published version. + + + + + +## Migration + + + +### Notes + +* Additional information about how to use the new `status` parameter can be found in the [REST API](/dev-docs/api/rest/filters-locale-publication#status), [GraphQL API](/dev-docs/api/graphql#status), and [Document Service API](/dev-docs/api/document-service/status) documentation. + +### Migration procedure + +* API calls initiated from the front end (REST API, GraphQL API) that used `publishedAt` need to be manually updated. diff --git a/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/upgrade-to-apollov4.md b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/upgrade-to-apollov4.md index 9a32229282..ac3affe578 100644 --- a/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/upgrade-to-apollov4.md +++ b/docusaurus/docs/dev-docs/migration/v4-to-v5/breaking-changes/upgrade-to-apollov4.md @@ -61,7 +61,7 @@ Apollo Server v4 for the GraphQL server and graphql ^16 for the GraphQL module. To migrate to Strapi 5: -- Set the `x-apollo-operation-name` header or disable the new protection by adding `csrfPrevention: false` to the GraphQL plugin configuration for multipart messages (file uploads). +- Set the `x-apollo-operation-name` header or disable the new protection by adding `csrfPrevention: false` to apolloServer in the GraphQL plugin configuration for multipart messages (file uploads). - Replace `ApolloError` with `GraphQLError`. - Remove root level configuration options like `formatResponse` and replace them with plugin hooks in the plugins array. - Remove the modules configuration option and split it into `typeDefs` and `resolvers`. diff --git a/docusaurus/docs/dev-docs/migration/v4-to-v5/introduction-and-faq.md b/docusaurus/docs/dev-docs/migration/v4-to-v5/introduction-and-faq.md index cd6b3a6136..37baea66d6 100644 --- a/docusaurus/docs/dev-docs/migration/v4-to-v5/introduction-and-faq.md +++ b/docusaurus/docs/dev-docs/migration/v4-to-v5/introduction-and-faq.md @@ -51,10 +51,6 @@ Strapi 5 docs also provide a [complete breaking changes database](/dev-docs/migr
As a Strapi Cloud customer, how can I handle the entire upgrade and deployment of my Strapi 5 application? -:::danger Warning: Don't push a Strapi 5 project to Strapi Cloud yet -Strapi Cloud is still running on Strapi v4. The following process is provided as an indication of what will happen when Strapi 5 is released as a stable version. Do not try to push your Strapi 5 beta or Release Candidate (RC) project to Strapi Cloud yet. -::: - 1. [Create a backup](/cloud/projects/settings#backups) and update your code locally, following the step-by-step guide. 2. Run the `yarn deploy` or `npm run deploy` commands from the [Cloud CLI](/cloud/cli/cloud-cli).
diff --git a/docusaurus/docs/dev-docs/migration/v4-to-v5/step-by-step.md b/docusaurus/docs/dev-docs/migration/v4-to-v5/step-by-step.md index ecadd9f863..385264abfe 100644 --- a/docusaurus/docs/dev-docs/migration/v4-to-v5/step-by-step.md +++ b/docusaurus/docs/dev-docs/migration/v4-to-v5/step-by-step.md @@ -14,7 +14,7 @@ const summaryStyle = {fontSize: '18px'} # Step-by-step guide to upgrade to Strapi 5 -The latest major version of Strapi is Strapi 5, which is currently provided as a Release Candidate (RC) version, not as a stable version yet. +The latest major version of Strapi is Strapi 5. The present page is meant to be used as step-by-step instructions for upgrading your Strapi v4 application to Strapi 5. @@ -116,7 +116,7 @@ Follow the steps below and leverage retro-compatibility flags and guided migrati ### Migrate GraphQL API calls -1. Enable the retro-compatibility flag by setting `v4ComptabilityMode` to `true` in the `graphl.config` object of [the `/config/plugins.js|ts` file](/dev-docs/configurations/plugins#graphql). +1. Enable the retro-compatibility flag by setting `v4CompatibilityMode` to `true` in the `graphl.config` object of [the `/config/plugins.js|ts` file](/dev-docs/configurations/plugins#graphql). 2. Update your queries and mutations only, guided by the dedicated [breaking change entry for GraphQL](/dev-docs/migration/v4-to-v5/breaking-changes/graphql-api-updated). 3. Validate that your client is running correctly. -4. Disable the retro-compatibily flag by setting `v4ComptabilityMode` to `true` and start using the new response format. +4. Disable the retro-compatibily flag by setting `v4CompatibilityMode` to `false` and start using the new response format. diff --git a/docusaurus/docs/dev-docs/plugins-extension.md b/docusaurus/docs/dev-docs/plugins-extension.md index 391a679d1b..c1e9fe81c3 100644 --- a/docusaurus/docs/dev-docs/plugins-extension.md +++ b/docusaurus/docs/dev-docs/plugins-extension.md @@ -12,12 +12,8 @@ tags: - services --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Plugins extension - - Strapi comes with [plugins](/dev-docs/plugins) that can be installed from the [Marketplace](/user-docs/plugins/installing-plugins-via-marketplace#installing-marketplace-plugins-and-providers) or as npm packages. You can also create your own plugins (see [plugins development](/dev-docs/plugins/developing-plugins)) or extend the existing ones. :::warning diff --git a/docusaurus/docs/dev-docs/plugins/admin-panel-api.md b/docusaurus/docs/dev-docs/plugins/admin-panel-api.md index ae6a7ff88e..63e9967e65 100644 --- a/docusaurus/docs/dev-docs/plugins/admin-panel-api.md +++ b/docusaurus/docs/dev-docs/plugins/admin-panel-api.md @@ -447,7 +447,7 @@ Both the `injectComponent()` and `getPlugin('content-manager').injectComponent() export default { bootstrap(app) { - app.getPlugin('content-manager').injectComponent()('editView', 'informations', { + app.getPlugin('content-manager').injectComponent('editView', 'informations', { name: 'my-plugin-my-compo', Component: () => 'my-compo', }); diff --git a/docusaurus/docs/dev-docs/plugins/development/create-a-plugin.md b/docusaurus/docs/dev-docs/plugins/development/create-a-plugin.md index 8160eed2f7..e0df1b9ce7 100644 --- a/docusaurus/docs/dev-docs/plugins/development/create-a-plugin.md +++ b/docusaurus/docs/dev-docs/plugins/development/create-a-plugin.md @@ -50,7 +50,7 @@ yarn dlx @strapi/sdk-plugin init my-strapi-plugin ```bash -npx @strapi/sdk-plugin:init my-strapi-plugin +npx @strapi/sdk-plugin init my-strapi-plugin ``` diff --git a/docusaurus/docs/dev-docs/plugins/documentation.md b/docusaurus/docs/dev-docs/plugins/documentation.md index aca0a24bf6..3dfcbbf87a 100644 --- a/docusaurus/docs/dev-docs/plugins/documentation.md +++ b/docusaurus/docs/dev-docs/plugins/documentation.md @@ -13,12 +13,8 @@ tags: - Swagger UI --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Documentation plugin - - The Documentation plugin is useful to document the available endpoints once you created an API. If installed, the Documentation plugin will inspect content types and routes found on all APIs in your project and any plugin specified in the configuration. The plugin will then programmatically generate documentation to match the [OpenAPI specification](https://swagger.io/specification/). The Documentation plugin generates the [paths objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#paths-object) and [schema objects](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.1.0.md#schema-object) and converts all Strapi types to [OpenAPI data types](https://swagger.io/docs/specification/data-models/data-types/). diff --git a/docusaurus/docs/dev-docs/plugins/graphql.md b/docusaurus/docs/dev-docs/plugins/graphql.md index 6b2a444b10..9a997756d5 100644 --- a/docusaurus/docs/dev-docs/plugins/graphql.md +++ b/docusaurus/docs/dev-docs/plugins/graphql.md @@ -17,12 +17,8 @@ tags: --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # GraphQL plugin - - By default Strapi create [REST endpoints](/dev-docs/api/rest#endpoints) for each of your content-types. With the GraphQL plugin, you will be able to add a GraphQL endpoint to fetch and mutate your content. :::strapi Looking for the GraphQL API documentation? diff --git a/docusaurus/docs/dev-docs/plugins/guides/pass-data-from-server-to-admin.md b/docusaurus/docs/dev-docs/plugins/guides/pass-data-from-server-to-admin.md index 7d5c7a4cda..71e3765f34 100644 --- a/docusaurus/docs/dev-docs/plugins/guides/pass-data-from-server-to-admin.md +++ b/docusaurus/docs/dev-docs/plugins/guides/pass-data-from-server-to-admin.md @@ -12,12 +12,8 @@ tags: - plugins development guides --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # How to pass data from server to admin panel with a Strapi plugin - - Strapi is **headless** . The admin panel is completely separate from the server. When [developing a Strapi plugin](/dev-docs/plugins/developing-plugins) you might want to pass data from the `/server` to the `/admin` folder. Within the `/server` folder you have access to the Strapi object and can do database queries whereas in the `/admin` folder you can't. diff --git a/docusaurus/docs/dev-docs/plugins/guides/store-and-access-data.md b/docusaurus/docs/dev-docs/plugins/guides/store-and-access-data.md index 85ab122cc1..bbdd5082e6 100644 --- a/docusaurus/docs/dev-docs/plugins/guides/store-and-access-data.md +++ b/docusaurus/docs/dev-docs/plugins/guides/store-and-access-data.md @@ -11,12 +11,8 @@ tags: - plugins development guides --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # How to store and access data from a Strapi plugin - - To store data with a Strapi [plugin](/dev-docs/plugins/developing-plugins), use a plugin content-type. Plugin content-types work exactly like other [content-types](/dev-docs/backend-customization/models). Once the content-type is [created](#create-a-content-type-for-your-plugin), you can start [interacting with the data](#interact-with-data-from-the-plugin). ## Create a content-type for your plugin diff --git a/docusaurus/docs/dev-docs/plugins/upload.md b/docusaurus/docs/dev-docs/plugins/upload.md index 6aafbd00ed..ca2158acac 100644 --- a/docusaurus/docs/dev-docs/plugins/upload.md +++ b/docusaurus/docs/dev-docs/plugins/upload.md @@ -11,12 +11,8 @@ tags: --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Upload plugin - - The Upload plugin is the backend powering the Media Library available by default in the Strapi admin panel. The Upload plugin is installed by default and can not be uninstalled. Using either the Media Library from the admin panel or the upload API directly, you can upload any kind of file for use in your Strapi application. By default Strapi provides a [provider](/dev-docs/providers) that uploads files to a local directory, which by default will be `public/uploads/` in your Strapi project. Additional providers are available should you want to upload your files to another location. diff --git a/docusaurus/docs/dev-docs/plugins/users-permissions.md b/docusaurus/docs/dev-docs/plugins/users-permissions.md index 3487ee2b52..bf86cf6fe9 100644 --- a/docusaurus/docs/dev-docs/plugins/users-permissions.md +++ b/docusaurus/docs/dev-docs/plugins/users-permissions.md @@ -161,7 +161,7 @@ Available options: - `jwtSecret`: random string used to create new JWTs, typically set using the `JWT_SECRET` [environment variable](/dev-docs/configurations/environment#strapi-s-environment-variables). - `jwt.expiresIn`: expressed in seconds or a string describing a time span.
- Eg: 60, "45m", "10h", "2 days", "7d", "2y". A numeric value is interpreted as a seconds count. If you use a string be sure you provide the time units (minutes, hours, days, years, etc), otherwise milliseconds unit is used by default ("120" is equal to "120ms"). + Eg: 60, "45m", "10h", "2 days", "7d", "2y". A numeric value is interpreted as a seconds count. If you need more advanced examples please see the [ms package](https://github.com/vercel/ms). @@ -1354,3 +1354,30 @@ If you need to configure a custom handler to accept other URLs, you can create a }, }, ``` + +### Creating a custom password validation + +To add password validation at the API level, you can create a custom function passed to `validationRules` in the configuration of the Users & Permissions plugin, as in the following example: + +```js title="/config/plugins.js|ts" + // ... other plugins configuration ... + // Users & Permissions configuration +'users-permissions': { + config: { + validationRules: { + validatePassword(value) { + if (value.length < 8) { + // custom error message + throw new Error('password should be more than 8 letters'); + } + + if (value.length > 24) { + // throws default error message + return false; + } + + return true; // Validation passed + }, + }, + }, + }, diff --git a/docusaurus/docs/dev-docs/quick-start.md b/docusaurus/docs/dev-docs/quick-start.md index c5b12c7501..908153337f 100644 --- a/docusaurus/docs/dev-docs/quick-start.md +++ b/docusaurus/docs/dev-docs/quick-start.md @@ -22,19 +22,20 @@ Strapi offers a lot of flexibility. Whether you want to go fast and quickly see *Estimated completion time: 5-10 minutes* -:::prerequisites +
+☑️ Prerequisites: + You will also need to [install `git`](https://github.com/git-guides/install-git) and to have a [GitHub](https://github.com) account to deploy your project to Strapi Cloud. -::: + +
## 🚀 Part A: Create a new project with Strapi We will first create a new Strapi project on your machine by running a command in the terminal, and then register our first local administrator user. -Follow the steps below by clicking on the togglable content to read more instructions. - -
+
Step 1: Run the installation script and create a Strapi Cloud account ### Step 1: Run the installation script and create a Strapi Cloud account diff --git a/docusaurus/docs/dev-docs/testing.md b/docusaurus/docs/dev-docs/testing.md index 6476bdad88..434de77916 100644 --- a/docusaurus/docs/dev-docs/testing.md +++ b/docusaurus/docs/dev-docs/testing.md @@ -8,12 +8,8 @@ tags: - environment --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Unit testing - - :::strapi The Strapi blog has a tutorial on how to implement [API testing with Jest and Supertest](https://strapi.io/blog/automated-testing-for-strapi-api-with-jest-and-supertest) and [how to add unit tests to your Strapi plugin](https://strapi.io/blog/how-to-add-unit-tests-to-your-strapi-plugin). ::: diff --git a/docusaurus/docs/dev-docs/typescript/development.md b/docusaurus/docs/dev-docs/typescript/development.md index 27f574388f..a2181acfc1 100644 --- a/docusaurus/docs/dev-docs/typescript/development.md +++ b/docusaurus/docs/dev-docs/typescript/development.md @@ -2,25 +2,27 @@ title: TypeScript development description: Learn more about TypeScript usage with Strapi 5 tags: -- strapi() factory -- strapi.compile() function -- typescript -- plugins development - + - strapi() factory + - strapi.compile() function + - typescript + - plugins development + - api + - guides --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' +# TypeScript Development with Strapi + +This page provides a comprehensive guide to developing with TypeScript in Strapi v5, covering key patterns and configurations for integrating TypeScript effectively. You'll find sections on using Strapi’s provided types, generating and managing typings for content types, configuring Strapi programmatically, and building plugins with TypeScript. Each section includes practical steps and example code to help you set up and troubleshoot TypeScript-based workflows in your Strapi project. -# TypeScript Development with Strapi +:::strapi API reference +We are preparing an API reference page, which will include an exhaustive list of the types exported by Strapi. Please come back soon! 👀 +::: - +## :books: Guides -While developing a [TypeScript](/dev-docs/typescript)-based application with Strapi, you can: +The guides are a curated list of common examples in which you might need to use Strapi types in your application. -- access [typings for the `Strapi`](#use-strapi-typescript-typings) class with autocompletion, -- [generate typings](#generate-typings-for-content-types-schemas) for your project's content-types, -- [start Strapi programmatically](#start-strapi-programmatically), -- and follow some TypeScript-specific instructions for [plugins development](#develop-a-plugin-using-typescript). +You can find the list of available guides [here](/dev-docs/typescript/development/guides). ## Use `Strapi` TypeScript typings @@ -31,15 +33,15 @@ To experience TypeScript-based autocomplete while developing Strapi applications 1. Open the `./src/index.ts` file from your code editor. 2. Declare the `strapi` argument as type `Strapi` within the global `register` method: - ```typescript title="./src/index.ts" - import { Strapi } from '@strapi/strapi'; + ```typescript title="./src/index.ts" + import type { Core } from '@strapi/strapi'; - export default { - register({ strapi }: { strapi: Strapi }) { - // ... - }, - }; - ``` + export default { + register({ strapi }: { strapi: Core.Strapi }) { + // ... + }, + }; + ``` 3. Within the body of the `register` method, start typing `strapi.` and use keyboard arrows to browse the available properties. @@ -111,15 +113,14 @@ Types should only be imported from `@strapi/strapi` to avoid breaking changes. T To start Strapi programmatically in a TypeScript project the Strapi instance requires the compiled code location. This section describes how to set and indicate the compiled code directory. -### Use the `strapi()` factory +### Use the `createStrapi()` factory -Strapi can be run programmatically by using the `strapi()` factory. Since the code of TypeScript projects is compiled in a specific directory, the parameter `distDir` should be passed to the factory to indicate where the compiled code should be read: +Strapi can be run programmatically by using the `strapi.createStrapi()` factory. Since the code of TypeScript projects is compiled in a specific directory, the parameter `distDir` should be passed to the factory to indicate where the compiled code should be read: ```js title="./server.js" - const strapi = require('@strapi/strapi'); -const app = strapi({ distDir: './dist' }); -app.start(); +const app = strapi.createStrapi({ distDir: './dist' }); +app.start(); ``` ### Use the `strapi.compile()` function @@ -129,7 +130,7 @@ The `strapi.compile()` function should be mostly used for developing tools that ```js const strapi = require('@strapi/strapi'); -strapi.compile().then(appContext => strapi(appContext).start()); +strapi.compile().then((appContext) => strapi(appContext).start()); ``` ## Develop a plugin using TypeScript diff --git a/docusaurus/docs/dev-docs/typescript/development/api-reference.md b/docusaurus/docs/dev-docs/typescript/development/api-reference.md new file mode 100644 index 0000000000..58486e18b7 --- /dev/null +++ b/docusaurus/docs/dev-docs/typescript/development/api-reference.md @@ -0,0 +1,12 @@ +--- +title: TypeScript - API Reference +sidebar_label: API Reference +description: API Reference for Strapi Type System +tags: + - typescript + - api +--- + +# API Reference + +:building_construction: **Still under construction, come back later** :construction: diff --git a/docusaurus/docs/dev-docs/typescript/development/guides.md b/docusaurus/docs/dev-docs/typescript/development/guides.md new file mode 100644 index 0000000000..db67c57c2d --- /dev/null +++ b/docusaurus/docs/dev-docs/typescript/development/guides.md @@ -0,0 +1,18 @@ +--- +title: TypeScript - Guides +sidebar_label: Guides +description: List of TypeScript guides to get started with Strapi and TypeScript +tags: + - typescript + - guides +--- + +# TypeScript Guides + +This page includes a curated list of common examples useful to use types while [developing a Strapi TypeScript application](/dev-docs/typescript/development). + + + + + + diff --git a/docusaurus/docs/dev-docs/typescript/development/guides/documents-and-entries.md b/docusaurus/docs/dev-docs/typescript/development/guides/documents-and-entries.md new file mode 100644 index 0000000000..ec288d7b2f --- /dev/null +++ b/docusaurus/docs/dev-docs/typescript/development/guides/documents-and-entries.md @@ -0,0 +1,214 @@ +--- +title: TypeScript - Manipulating Documents and Entries +sidebar_label: Manipulating Documents and Entries +description: TypeScript guide to get started with manipulating documents and entries +tags: + - typescript + - guides + - data + - document + - component + - uid + - entries +--- + +# Manipulating documents and entries + +This guide will explore TypeScript patterns for manipulating documents and entries in a Strapi v5 application, including how to leverage Strapi's `UID` and `Data` namespaces to interact with both generic and known entity types safely. If you're working on a TypeScript-based Strapi project, mastering these approaches will help you take full advantage of type safety and code completion, ensuring robust, error-free interactions with your application’s content and components. + +:::prerequisites + +- **Strapi Application:** A Strapi v5 application. If you don't have one, follow the [documentation](/dev-docs/quick-start) to get started. +- **TypeScript:** Ensure TypeScript is set up in your Strapi project. You can follow Strapi's [official guide](/dev-docs/typescript#getting-started-with-typescript-in-strapi) on configuring TypeScript. +- **Generated Types:** Application types [have been generated](/dev-docs/typescript/development#generate-typings-for-content-types-schemas) and are accessible. + ::: + +## Type Imports + +The `UID` namespace contains literal unions representing the available resources in the application. + +```typescript +import type { UID } from '@strapi/strapi'; +``` + +- `UID.ContentType` represents a union of every content-type identifier in the application +- `UID.Component` represents a union of every component identifier in the application +- `UID.Schema` represents a union of every schema (content-type or component) identifier in the application +- And others... + +--- + +Strapi provides a `Data` namespace containing several built-in types for entity representation. + +```typescript +import type { Data } from '@strapi/strapi'; +``` + +- `Data.ContentType` represents a Strapi document object +- `Data.Component` represents a Strapi component object +- `Data.Entity` represents either a document or a component + +:::tip +Both the entities' type definitions and UIDs are based on the generated schema types for your application. + +In case of a mismatch or error, you can always [regenerate the types](/dev-docs/typescript/development#generate-typings-for-content-types-schemas). +::: + +## Usage + +### Generic entities + +When dealing with generic data, it is recommended to use non-parametrized forms of the `Data` types. + +#### Generic documents + +```typescript +async function save(name: string, document: Data.ContentType) { + await writeCSV(name, document); + // ^ { + // id: Data.ID; + // documentId: string; + // createdAt?: DateTimeValue; + // updatedAt?: DateTimeValue; + // publishedAt?: DateTimeValue; + // ... + // } +} +``` + +:::warning +In the preceding example, the resolved properties for `document` are those common to every content-type. + +Other properties have to be checked manually using type guards. + +```typescript +if ('my_prop' in document) { + return document.my_prop; +} +``` + +::: + +#### Generic components + +```typescript +function renderComponent(parent: Node, component: Data.Component) { + const elements: Element[] = []; + const properties = Object.entries(component); + + for (const [name, value] of properties) { + // ^ ^ + // string any + const paragraph = document.createElement('p'); + + paragraph.textContent = `Key: ${name}, Value: ${value}`; + + elements.push(paragraph); + } + + parent.append(...elements); +} +``` + +### Known entities + +When manipulating known entities, it is possible to parametrize `Data` types for better type safety and code completion. + +#### Known documents + +```typescript +const ALL_CATEGORIES = ['food', 'tech', 'travel']; + +function validateArticle(article: Data.ContentType<'api::article.article'>) { + const { title, category } = article; + // ^? ^? + // string Data.ContentType<'api::category.category'> + + if (title.length < 5) { + throw new Error('Title too short'); + } + + if (!ALL_CATEGORIES.includes(category.name)) { + throw new Error(`Unknown category ${category.name}`); + } +} +``` + +#### Known components + +```typescript +function processUsageMetrics( + id: string, + metrics: Data.Component<'app.metrics'> +) { + telemetry.send(id, { clicks: metrics.clicks, views: metrics.views }); +} +``` + +### Advanced use cases + +#### Entities subsets + +Using the types' second parameter (`TKeys`), it is possible to obtain a subset of an entity. + +```typescript +type Credentials = Data.ContentType<'api::acount.acount', 'email' | 'password'>; +// ^? { email: string; password: string } +``` + +```typescript +type UsageMetrics = Data.Component<'app.metrics', 'clicks' | 'views'>; +// ^? { clicks: number; views: number } +``` + +#### Type argument inference + +It is possible to bind and restrict an entity type based on other function parameters. + +In the following example, the `uid` type is inferred upon usage as `T` and used as a type parameter for the `document`. + +```typescript +import type { UID } from '@strapi/strapi'; + +function display( + uid: T, + document: Data.ContentType +) { + switch (uid) { + case 'api::article.article': { + return document.title; + // ^? string + // ^? Data.ContentType<'api::article.article'> + } + case 'api::category.category': { + return document.name; + // ^? string + // ^? Data.ContentType<'api::category.category'> + } + case 'api::account.account': { + return document.email; + // ^? string + // ^? Data.ContentType<'api::account.account'> + } + default: { + throw new Error(`unknown content-type uid: "${uid}"`); + } + } +} +``` + +When calling the function, the `document` type needs to match the given `uid`. + +```typescript +declare const article: Data.Document<'api::article.article'>; +declare const category: Data.Document<'api::category.category'>; +declare const account: Data.Document<'api::account.account'>; + +display('api::article.article', article); +display('api::category.category', category); +display('api::account.account', account); +// ^ ✅ + +display('api::article.article', category); +// ^ Error: "category" is not assignable to parameter of type ContentType<'api::article.article'> +``` diff --git a/docusaurus/docs/dev-docs/upgrade-tool.md b/docusaurus/docs/dev-docs/upgrade-tool.md index 75a84ae743..1026b24bae 100644 --- a/docusaurus/docs/dev-docs/upgrade-tool.md +++ b/docusaurus/docs/dev-docs/upgrade-tool.md @@ -55,20 +55,25 @@ Strapi version numbers respect the [semantic versioning](https://semver.org/) co - The second number is the **minor** version number. - The third number is the **patch** version number. -The upgrade tool allows upgrading to a major, minor, or patch version. +The upgrade tool allows upgrading to a `major`, `minor`, or `patch` version. -What the upgrade tool does depends on the latest existing version and the command you run. +Alternatively, you can choose to upgrade to the `latest` available version. -For instance, if the latest Strapi v4 version is v4.25.9: +What the upgrade tool does depends on three things: -| My Strapi application is currently on… | If I run… | My Strapi application will be upgraded to … | -|----------------------------------------|-----------------------------|--------------------------------------------------------------------------------------------| -| v4.25.1 | `npx @strapi/upgrade patch` | v4.25.9

(because v4.25.9 is the latest patch version for the v4.25 minor version) | -| v4.14.1 | `npx @strapi/upgrade minor` | v4.25.9 | -| v4.14.1 | `npx @strapi/upgrade major` | Nothing.

I first need to run `npx @strapi/upgrade minor` to upgrade to v4.25.9. | -| v4.25.9 | `npx @strapi/upgrade major` | v5.0.0 | +- the project Strapi version +- the latest available version of Strapi +- the command you run. +For instance, if the latest Strapi v4 version is v4.25.9, and the latest Strapi v5 version is v5.1.2: +| My Strapi application is currently on… | If I run… | My Strapi application will be upgraded to … | +|----------------------------------------|------------------------------|-------------------------------------------------------------------------------------------------| +| v4.25.1 | `npx @strapi/upgrade patch` | v4.25.9

(because v4.25.9 is the latest patch version for the v4.25 minor version) | +| v4.14.1 | `npx @strapi/upgrade minor` | v4.25.9 | +| v4.14.1 | `npx @strapi/upgrade major` | Nothing.

I first need to run `npx @strapi/upgrade minor` to upgrade to v4.25.9. | +| v4.25.9 | `npx @strapi/upgrade major` | v5.1.2 | +| v4.14.1 | `npx @strapi/upgrade latest` | v5.1.2

A confirmation prompt appears to make sure the major version bump is intended. | ## Upgrade to a new version @@ -78,21 +83,23 @@ Before running the upgrade process, make sure you've created a backup of your co ### Upgrade to a major version -Run the upgrade tool with the `major` parameter to upgrade the project to the next major version of Strapi: +Run the upgrade tool with the `major` parameter to upgrade the project to the latest release of the next major Strapi version: ```bash npx @strapi/upgrade major ``` -During the upgrade process, the application dependencies are updated and installed, and the related codemods are executed. +During the upgrade process, the application dependencies are updated and installed, and the related codemods are executed (if any). :::note -If your application is not already running the latest minor and patch version in the current major, the `major` upgrade is prevented, and you will first need to upgrade to the latest [minor.patch](#upgrade-to-a-minor-version) version in the current major version. This means that moving from v4.14.4 to v5.0.0 is a 2-step process because the latest v4 version is v4.16.2. +If your application is not already running the latest minor and patch version in the current major, the `major` upgrade is prevented, and you will first need to upgrade to the latest [minor.patch](#upgrade-to-a-minor-version) version in the current major version. + +This means that moving from v4.14.4 to v5.0.0 is a 2-step process because the latest v4 version is v4.16.2. ::: ### Upgrade to a minor version -Run the upgrade tool with the `minor` parameter to upgrade the project to the latest minor and patch version of Strapi: +Run the upgrade tool with the `minor` parameter to upgrade the project to the latest minor and patch version of Strapi for the current major: ```bash npx @strapi/upgrade minor @@ -110,6 +117,23 @@ npx @strapi/upgrade patch During the upgrade process, the project dependencies are updated and installed, and the related codemods are executed (if any). +### Upgrade to the latest version + +Run the upgrade tool with the `latest` parameter to upgrade the project to the latest available version regardless of the current Strapi version: + +```bash +npx @strapi/upgrade latest +``` + +During the upgrade process, the project dependencies are updated and installed, and the related codemods are executed (if any). + +:::note +If a `major` version upgrade is detected, the upgrade tool displays a confirmation prompt to make sure the change is +intended. + +In the scenario where the major bump isn't the desired option, see [the minor upgrade](#upgrade-to-a-minor-version). +::: + ## Run codemods only Run the upgrade tool with the `codemods` parameter to execute a utility that allows selecting the codemods to be executed. With this command, only the codemods are run, the dependencies are not updated nor installed. @@ -136,20 +160,20 @@ npx @strapi/upgrade codemods run 5.0.0-strapi-codemod-uid The `npx @strapi/upgrade [major|minor|patch]` commands can accept the following options: -| Option | Description | Default | -| --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------|----------| -| [`-n, --dry`](#simulate-the-upgrade-without-updating-any-files-dry-run) | [Simulate](#simulate-the-upgrade-without-updating-any-files-dry-run) the upgrade without updating any files | false | -| [`-d, --debug`](#get-detailed-debugging-information) | Get [more logs](#get-detailed-debugging-information) in debug mode | false | -| [`-s, --silent`](#execute-the-upgrade-silently) | [Don't log anything](#execute-the-upgrade-silently) | false | -| [`-p, --project-path `](#select-a-path-for-the-strapi-application-folder) | [Path](#select-a-path-for-the-strapi-application-folder) to the Strapi project | - | -| [`-y, --yes`](#answer-yes-to-every-prompt) | Automatically [answer "yes"](#answer-yes-to-every-prompt) to every prompt | false | +| Option | Description | Default | +|-----------------------------------------------------------------------------------------|-------------------------------------------------------------------------------------------------------------|---------| +| [`-n, --dry`](#simulate-the-upgrade-without-updating-any-files-dry-run) | [Simulate](#simulate-the-upgrade-without-updating-any-files-dry-run) the upgrade without updating any files | false | +| [`-d, --debug`](#get-detailed-debugging-information) | Get [more logs](#get-detailed-debugging-information) in debug mode | false | +| [`-s, --silent`](#execute-the-upgrade-silently) | [Don't log anything](#execute-the-upgrade-silently) | false | +| [`-p, --project-path `](#select-a-path-for-the-strapi-application-folder) | [Path](#select-a-path-for-the-strapi-application-folder) to the Strapi project | - | +| [`-y, --yes`](#answer-yes-to-every-prompt) | Automatically [answer "yes"](#answer-yes-to-every-prompt) to every prompt | false | -The following options can be run either with the `npx @strapi/upgrade` command alone or with the `npx @strapi/upgrade [major|minor|patch]` commands: +The following options can be run either with the `npx @strapi/upgrade` command alone or with the `npx @strapi/upgrade [major|minor|patch|latest]` commands: -| Option | Description | -| ------------------------------------------------------------------------ | ---------------------------------------------------------------- | -| [`-V, --version`](#get-the-current-version) | Output the [version number](#get-the-current-version) | -| [`-h, --help`](#get-help) | [Print](#get-help) command line options | +| Option | Description | +|---------------------------------------------|-------------------------------------------------------| +| [`-V, --version`](#get-the-current-version) | Output the [version number](#get-the-current-version) | +| [`-h, --help`](#get-help) | [Print](#get-help) command line options | ### Simulate the upgrade without updating any files (dry run) @@ -161,6 +185,7 @@ Examples: npx @strapi/upgrade major --dry npx @strapi/upgrade minor --dry npx @strapi/upgrade patch --dry +npx @strapi/upgrade latest --dry ``` ### Select a path for the Strapi application folder @@ -226,9 +251,10 @@ Options: -h, --help Print command line options Commands: - major [options] Upgrade to the next available major version of Strapi + major [options] Upgrade to ... minor [options] Upgrade to ... patch [options] Upgrade to ... + latest [options] Upgrade to ... help [command] Print options for a specific command ``` diff --git a/docusaurus/docs/release-notes.md b/docusaurus/docs/release-notes.md index 570ab20254..0b2e4c47b3 100644 --- a/docusaurus/docs/release-notes.md +++ b/docusaurus/docs/release-notes.md @@ -18,13 +18,272 @@ Since Strapi Docs version 5.0.0, the **docs' version number is independent from Strapi Docs now follow the **[semantic versioning](https://semver.org/)** philosophy, but adapted to docs: - **Major version** (6.0.0, 7.0.0…): A **significant rewrite** of the docs (content or framework). This may impact the user experience, redesign the site, or break old links (redirections are handled, but broken links can be [reported](https://github.com/strapi/documentation/issues/new/choose)). -- **Minor version** (5.1.0, 5.2.0…): **New Strapi features or improvements** to the docs (e.g., new components or tools). +- **Minor version** (5.1.0, 5.2.0…): **New Strapi features** or improvements to the docs (e.g., new components or tools). - **Patch version** (5.1.1, 5.1.2…): **Content updates**, including improvement or extension of existing pages, code examples fixes, and typos. New versions (minor or patch) are generally released weekly, on Wednesdays.
+## 5.2.1 + +### 🖌 Updated content + +- [Add `strapi cloud environment link` to Cloud CLI](https://github.com/strapi/documentation/pull/2282) +- [Add new Cloud regions](https://github.com/strapi/documentation/pull/2290) + +### 🧹 Chore, fixes, typos, and other improvements + +#### Dev Docs +- [Add useTypescriptMigrations](https://github.com/strapi/documentation/pull/2283) +- [Fix typo in retro-compatibility flag value](https://github.com/strapi/documentation/pull/2294) +- [Fix typo in example code for injectComponent in Admin Panel API docs ](https://github.com/strapi/documentation/pull/2287) +- [Fix outdated mention of Gold plan in SSO docs](https://github.com/strapi/documentation/pull/2286) +- [Fix locale param. example in Interactive Query Builder](https://github.com/strapi/documentation/pull/2285) +- [Fix discardDraft() Document Service API example](https://github.com/strapi/documentation/pull/2284) + +#### Strapi Cloud +- [Update credit cards handling](https://github.com/strapi/documentation/pull/2262) + +#### Repository +- [Add release notes script](https://github.com/strapi/documentation/pull/2289) + +*** +This release was made possible thanks to the following contributors. Thank you! 🫶 + +
+
+ + +## 5.2.0 + +### ✨ New content + +#### Dev Docs + +- [Add WIP API Reference and Guides for TypeScript](https://github.com/strapi/documentation/pull/2266) + +### 🖌 Updated content + +#### Dev Docs + +- [Add Knex Config function support](https://github.com/strapi/documentation/pull/2252) + +#### User Guide + +- [Integration between the Releases and Review Workflows features](https://github.com/strapi/documentation/pull/2273) + +### 🧹 Chore, fixes, typos, and other improvement + +#### Cloud + +- [Minor Cloud Docs changes](https://github.com/strapi/documentation/pull/2264) +- [Remove Strapi 5 warning for Cloud in FAQ](https://github.com/strapi/documentation/pull/2272) +- [Move custom cloud provider config warnings higher](https://github.com/strapi/documentation/pull/2278) + +#### Dev Docs + +- [Fix example request for update method in Document Service API](https://github.com/strapi/documentation/pull/2275) + +#### Repo + +- [Align navbar search box with 100% width](https://github.com/strapi/documentation/pull/2280) + +*** + +This release was made possible thanks to the following contributors. Thank you! 🫶 + + + +
+
+ +## 5.1.3 + +### 🧹 Chore, fixes, typos, and other improvements + +- [Improve instructions for upgrading to Apollo v4](https://github.com/strapi/documentation/pull/2271) +- [Fix code example in breaking change for new response format](https://github.com/strapi/documentation/pull/2270) +- [Update names of removed mutations in GraphQL breaking change](https://github.com/strapi/documentation/pull/2269) +- [Fix typo in a snippet used in Cloud docs](https://github.com/strapi/documentation/pull/2268) + +*** + +This release was made possible thanks to the following contributors. Thank you! 🫶 + +
+ + laurenskling + + + xxtf1z + +
+ +
+
+ +## 5.1.2 + +### 🖌 Updated content + +#### Dev Docs + +- [Add support for 'latest' parameter in the upgrade tool](https://github.com/strapi/documentation/pull/2259) +- [Add example code and resulting screenshot for theme extension](https://github.com/strapi/documentation/pull/2261) + +### 🧹 Chore, fixes, typos, and other improvements + +#### Strapi Cloud + +- [Update cloud deployment logs screen](https://github.com/strapi/documentation/pull/2263) +- [Update confirmation modal text in Cloud Update Repository](https://github.com/strapi/documentation/pull/2258) + +#### Repository + +- [Restore bigger font-size for categories title in sidebar](https://github.com/strapi/documentation/pull/2260) + +*** + +This release was made possible thanks to the following contributors. Thank you! 🫶 + +
+ + Convly + + + giu1io + + + pwizla + + +
+ +
+
+ +## 5.1.1 + +### 🖌 Updated content + +#### Strapi Cloud + +* [List environments with Cloud CLI](https://github.com/strapi/documentation/pull/2239) + +#### Dev Docs + +* [`publicationAt` breaking change](https://github.com/strapi/documentation/pull/2249) + +### 🧹 Chore, fixes, typos, and other improvements + +#### Strapi Cloud + +* [Update wording on purchasable extra Seats](https://github.com/strapi/documentation/pull/2238) + +#### Dev Docs + +* [Clarify sorting for relational fields in the Content Manager list view](https://github.com/strapi/documentation/pull/2224) +* [Fix typo for `v4CompatibilityMode` flag](https://github.com/strapi/documentation/pull/2257) +* [Fix step-by-step v4 → v5 migration (v4CompatibilityMode flag)](https://github.com/strapi/documentation/pull/2255) +* [Update environment declaration in Docker guide](https://github.com/strapi/documentation/pull/2253) +* [Fix createStrapi method in TypeScript development documentation](https://github.com/strapi/documentation/pull/2248) +* [Fix links in the REST API documentation](https://github.com/strapi/documentation/pull/2247) +* [Fix CheckPagePermissions code example in helper-plugin deprecation guide](https://github.com/strapi/documentation/pull/2244) +* [Fix typo for init command in Plugin SDK](https://github.com/strapi/documentation/pull/2243) +* [Add link to ms package for examples for JWT expiresIn](https://github.com/strapi/documentation/pull/2242) + +#### Repository + +* [Update LICENSE](https://github.com/strapi/documentation/pull/2251) + + +*** + +This release was made possible thanks to the following contributors. Thank you! 🫶 + + + +
+
+ ## 5.1.0 ### ✨ New content diff --git a/docusaurus/docs/snippets/configuration-sso-admin.md b/docusaurus/docs/snippets/configuration-sso-admin.md new file mode 100644 index 0000000000..b4dd02c499 --- /dev/null +++ b/docusaurus/docs/snippets/configuration-sso-admin.md @@ -0,0 +1,57 @@ +There are some optional configurations that you can set should it be necessary, for more information on available options please see the [Admin Configuration](/dev-docs/configurations/admin-panel) documentation. + +- **`url`**: The public facing URL of your Strapi administration panel. (e.g. `https://admin.example.com`) +- **`auth.domain`**: Setting a custom domain for cookie storage. (e.g. `.example.com`) + +:::note +When deploying the admin panel to a different location or on a different subdomain, an additional configuration is required to set the common domain for the cookies. This is required to ensure the cookies are shared across the domains. +::: + +:::caution +Deploying the admin and backend on entirely different unrelated domains is not possible at this time when using SSO due to restrictions in cross-domain cookies. +::: + +
+ Admin Optional Configuration Example + + + + + +```js title="./config/admin.js" + +module.exports = ({ env }) => ({ + // ... + url: env('PUBLIC_ADMIN_URL', 'https://admin.example.com'), + auth: { + domain: env("ADMIN_SSO_DOMAIN", ".example.com"), + providers: [ + // ... + ], + }, + // ... +}); +``` + + + + + +```ts title="./config/admin.ts" + +export default ({ env }) => ({ + // ... + url: env('PUBLIC_ADMIN_URL', 'https://admin.example.com'), + auth: { + domain: env("ADMIN_SSO_DOMAIN", ".example.com"), + providers: [ + // ... + ], + }, + // ... +}); +``` + + + +
diff --git a/docusaurus/docs/snippets/configuration-sso-middlewares.md b/docusaurus/docs/snippets/configuration-sso-middlewares.md new file mode 100644 index 0000000000..19ac73bfa8 --- /dev/null +++ b/docusaurus/docs/snippets/configuration-sso-middlewares.md @@ -0,0 +1,87 @@ +The following middleware configurations are required when using SSO, for more information on available options please see the [Middlewares Configuration](/dev-docs/configurations/middlewares) documentation. + +- **`contentSecurityPolicy`**: Allows you to configure the Content Security Policy (CSP) for your Strapi application. This is used to prevent cross-site scripting attacks by allowing you to control what resources can be loaded by your application. + +:::note +By default, Strapi security policy does not allow loading images from external URLs, so provider logos will not show up on the [login screen](/user-docs/intro#accessing-the-admin-panel) of the admin panel unless [a security exception is added](/dev-docs/configurations/middlewares#security) or you use a file uploaded directly on your Strapi application. +::: + +
+ Middlewares Configuration Example + + + + +```jsx title="./config/middlewares.js" +module.exports = [ + // ... + { + name: 'strapi::security', + config: { + contentSecurityPolicy: { + useDefaults: true, + directives: { + 'connect-src': ["'self'", 'https:'], + 'img-src': [ + "'self'", + 'data:', + 'blob:', + 'market-assets.strapi.io', + 'cdn2.iconfinder.com', // Base URL of the provider's logo without the protocol + ], + 'media-src': [ + "'self'", + 'data:', + 'blob:', + 'market-assets.strapi.io', + 'cdn2.iconfinder.com', // Base URL of the provider's logo without the protocol + ], + upgradeInsecureRequests: null, + }, + }, + }, + }, + // ... +] +``` + + + + + +```ts title="./config/middlewares.ts" +export default [ + // ... + { + name: 'strapi::security', + config: { + contentSecurityPolicy: { + useDefaults: true, + directives: { + 'connect-src': ["'self'", 'https:'], + 'img-src': [ + "'self'", + 'data:', + 'blob:', + 'market-assets.strapi.io', + 'cdn2.iconfinder.com', // Base URL of the provider's logo without the protocol + ], + 'media-src': [ + "'self'", + 'data:', + 'blob:', + 'market-assets.strapi.io', + 'cdn2.iconfinder.com', // Base URL of the provider's logo without the protocol + ], + upgradeInsecureRequests: null, + }, + }, + }, + }, + // ... +] +``` + + + +
diff --git a/docusaurus/docs/snippets/configuration-sso-server.md b/docusaurus/docs/snippets/configuration-sso-server.md new file mode 100644 index 0000000000..ec23be45e2 --- /dev/null +++ b/docusaurus/docs/snippets/configuration-sso-server.md @@ -0,0 +1,88 @@ +The following server configurations are required when using SSO, for more information on available options please see the [Server Configuration](/dev-docs/configurations/server) documentation. + +- **`url`**: The public facing URL of your Strapi application. (e.g. `https://api.example.com`) +- **`proxy.koa`**: Enabling trusted reverse proxy support. (`true`) + +
+ Admin Required Configuration Example + + + + + +```js title="./config/server.js" + +module.exports = ({ env }) => ({ + // ... + url: env('PUBLIC_URL', 'https://api.example.com'), + proxy: { + koa: env.bool('TRUST_PROXY', true), + }, + // ... +}); +``` + + + + + +```ts title="./config/server.ts" + +export default ({ env }) => ({ + // ... + url: env('PUBLIC_URL', 'https://api.example.com'), + proxy: { + koa: env.bool('TRUST_PROXY', true), + }, + // ... +}); +``` + + + +
+ +There are also some optional configurations that you can set should it be necessary: + +- **`proxy.global`**: If you are in a restricted network environment that requires a forward proxy (e.g Squid) for all outgoing requests. (e.g. `http://username:password@yourProxy:3128`) + +
+ Admin Optional Configuration Example + + + + + +```js title="./config/server.js" + +module.exports = ({ env }) => ({ + // ... + url: env('PUBLIC_URL', 'https://api.example.com'), + proxy: { + koa: env.bool('TRUST_PROXY', true), + global: env('GLOBAL_PROXY'), + }, + // ... +}); +``` + + + + + +```ts title="./config/server.ts" + +export default ({ env }) => ({ + // ... + url: env('PUBLIC_URL', 'https://api.example.com'), + proxy: { + koa: env.bool('TRUST_PROXY', true), + global: env('GLOBAL_PROXY'), + }, + // ... +}); +``` + + + +
diff --git a/docusaurus/docs/snippets/invoices-statuses.md b/docusaurus/docs/snippets/invoices-statuses.md index 8d3aac62e3..66a4f462cd 100644 --- a/docusaurus/docs/snippets/invoices-statuses.md +++ b/docusaurus/docs/snippets/invoices-statuses.md @@ -2,10 +2,10 @@ Invoices can have any of the following statuses: - Paid: the payment has been done and the invoice is available, no additional action is required. - Payment pending: the invoice is not complete or validated yet -- Payment due: the paiement didn't go through and needs to be fixed +- Payment due: the payment didn't go through and needs to be fixed - Not paid: the payment has failed and won't automatically be retried - Voided: the invoice has been cancelled. :::tip Click the ![download icon](/img/assets/icons/download.svg) icon to download an invoice. -::: \ No newline at end of file +::: diff --git a/docusaurus/docs/user-docs/content-manager/adding-content-to-releases.md b/docusaurus/docs/user-docs/content-manager/adding-content-to-releases.md index ae58312ba2..47e0e2e6fc 100644 --- a/docusaurus/docs/user-docs/content-manager/adding-content-to-releases.md +++ b/docusaurus/docs/user-docs/content-manager/adding-content-to-releases.md @@ -9,8 +9,6 @@ tags: - Strapi Cloud --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Including content in a release Using the [Releases](/user-docs/releases/introduction) feature, you can group several entries to publish them altogether. Adding entries to a release is done from the Content Manager. You can also remove an entry from a release while updating the entry. diff --git a/docusaurus/docs/user-docs/content-manager/configuring-view-of-content-type.md b/docusaurus/docs/user-docs/content-manager/configuring-view-of-content-type.md index fa5d40f619..071090c03a 100644 --- a/docusaurus/docs/user-docs/content-manager/configuring-view-of-content-type.md +++ b/docusaurus/docs/user-docs/content-manager/configuring-view-of-content-type.md @@ -10,8 +10,6 @@ tags: - Content-type edit view --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Configuring the views of a content-type Depending on their type, content-types can be divided into 2 interfaces: the list view and the edit view. Both interfaces can be configured. @@ -74,10 +72,8 @@ Relational fields can also be displayed in the list view. There are however some - Only first-level fields can be displayed (i.e. fields from the relation of a relation can't be displayed). - If the displayed field contains more than one value, not all its values will be displayed, but a counter indicating the number of values. You can hover this counter to see a tooltip indicating the first 10 values of the relational field. -Note also that relational fields have a couple limitations when it comes to sorting options: +Note also that relational fields cannot be set as default sort. -- Sorting cannot be enabled for relational fields which display several fields. -- Relational fields cannot be set as default sort. ::: ## Configuring the edit view diff --git a/docusaurus/docs/user-docs/content-manager/introduction-to-content-manager.md b/docusaurus/docs/user-docs/content-manager/introduction-to-content-manager.md index 4016c5391f..923bd11db0 100644 --- a/docusaurus/docs/user-docs/content-manager/introduction-to-content-manager.md +++ b/docusaurus/docs/user-docs/content-manager/introduction-to-content-manager.md @@ -13,7 +13,6 @@ tags: - introduction --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ScreenshotNumberReference from '/src/components/ScreenshotNumberReference.jsx'; # Introduction to the Content Manager diff --git a/docusaurus/docs/user-docs/content-manager/managing-relational-fields.md b/docusaurus/docs/user-docs/content-manager/managing-relational-fields.md index 93cf091854..35403a1e13 100644 --- a/docusaurus/docs/user-docs/content-manager/managing-relational-fields.md +++ b/docusaurus/docs/user-docs/content-manager/managing-relational-fields.md @@ -10,8 +10,6 @@ tags: - one-choice relational fields --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Managing relational fields Relation-type fields added to a content-type from the Content-type Builder allow establishing a relation with another collection type. These fields are called "relational fields". diff --git a/docusaurus/docs/user-docs/content-manager/reviewing-content.md b/docusaurus/docs/user-docs/content-manager/reviewing-content.md index 4aec74ab59..9880c329f1 100644 --- a/docusaurus/docs/user-docs/content-manager/reviewing-content.md +++ b/docusaurus/docs/user-docs/content-manager/reviewing-content.md @@ -7,8 +7,6 @@ tags: - review workflows --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Reviewing content Using the [Review Workflows](/user-docs/settings/review-workflows) feature, you can manage content throughout the content creation process. In the Content Manager, you can change the review stage of the content from the edit view, and keep moving it between stages as needed. You can also change the assignee of the content, assigning it to a Strapi admin user for review. diff --git a/docusaurus/docs/user-docs/content-manager/saving-and-publishing-content.md b/docusaurus/docs/user-docs/content-manager/saving-and-publishing-content.md index 5805735ea2..d19e7b79dd 100644 --- a/docusaurus/docs/user-docs/content-manager/saving-and-publishing-content.md +++ b/docusaurus/docs/user-docs/content-manager/saving-and-publishing-content.md @@ -10,8 +10,6 @@ tags: - unpublishing content --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Saving, publishing and deleting content Strapi allows you to manage your content throughout its whole lifecycle, whether you are working on its draft version, about to finish it and share it with the world, or wanting to delete it when it's obsolete. diff --git a/docusaurus/docs/user-docs/content-manager/translating-content.md b/docusaurus/docs/user-docs/content-manager/translating-content.md index 2546c8f214..fde21064f1 100644 --- a/docusaurus/docs/user-docs/content-manager/translating-content.md +++ b/docusaurus/docs/user-docs/content-manager/translating-content.md @@ -12,8 +12,6 @@ tags: - single type --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Translating content With the [Internationalization feature](/user-docs/plugins/strapi-plugins#-internationalization-plugin) enabled for a content-type, it is possible to manage content in more than one language, called "locale". To manage content in a specific locale, the latter must be added beforehand through the Internationalization settings (see [Configuring Internationalization locales](../settings/internationalization)). diff --git a/docusaurus/docs/user-docs/content-manager/working-with-content-history.md b/docusaurus/docs/user-docs/content-manager/working-with-content-history.md index 9e233562ed..6b4602f0d2 100644 --- a/docusaurus/docs/user-docs/content-manager/working-with-content-history.md +++ b/docusaurus/docs/user-docs/content-manager/working-with-content-history.md @@ -7,7 +7,7 @@ tags: - Content History --- -# Content History +# Content History The Content History feature of the Content Manager gives you the ability to browse and restore previous versions of documents created with the Content Manager. diff --git a/docusaurus/docs/user-docs/content-type-builder/configuring-fields-content-type.md b/docusaurus/docs/user-docs/content-type-builder/configuring-fields-content-type.md index 1c853042ad..04fd3de91e 100644 --- a/docusaurus/docs/user-docs/content-type-builder/configuring-fields-content-type.md +++ b/docusaurus/docs/user-docs/content-type-builder/configuring-fields-content-type.md @@ -12,8 +12,6 @@ tags: - password --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Configuring fields for content-types :::note Development-only @@ -49,7 +47,7 @@ The Text field displays a textbox that can contain small text. This field can be | Setting name | Instructions | |--------------|---------------------------------------------------------------------------------------------------------| | Name | Write the name of the Text field. | -| Type | Choose between *Short text* and *Long text*, to allow more or less space to fill up the Text field. | +| Type | Choose between *Short text* (255 characters maximum) and *Long text*, to allow more or less space to fill up the Text field. | @@ -160,7 +158,7 @@ The Date field can display a date (year, month, day), time (hour, minute, second - +### Password The Password field displays a password field that is encrypted. diff --git a/docusaurus/docs/user-docs/content-type-builder/creating-new-content-type.md b/docusaurus/docs/user-docs/content-type-builder/creating-new-content-type.md index a6f04b62f1..ccfb5473ac 100644 --- a/docusaurus/docs/user-docs/content-type-builder/creating-new-content-type.md +++ b/docusaurus/docs/user-docs/content-type-builder/creating-new-content-type.md @@ -9,8 +9,6 @@ tags: - single type --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Creating content-types :::note Development-only diff --git a/docusaurus/docs/user-docs/content-type-builder/introduction-to-content-types-builder.md b/docusaurus/docs/user-docs/content-type-builder/introduction-to-content-types-builder.md index b56cc4a551..4700458743 100644 --- a/docusaurus/docs/user-docs/content-type-builder/introduction-to-content-types-builder.md +++ b/docusaurus/docs/user-docs/content-type-builder/introduction-to-content-types-builder.md @@ -11,8 +11,6 @@ tags: pagination_next: user-docs/content-type-builder/creating-new-content-type --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Introduction to the Content-type Builder The Content-type Builder is a core plugin of Strapi. It is a feature that is always activated by default and cannot be deactivated. The Content-type Builder is however only accessible when the application is in a development environment. diff --git a/docusaurus/docs/user-docs/content-type-builder/managing-content-types.md b/docusaurus/docs/user-docs/content-type-builder/managing-content-types.md index e026b0e20a..528c1b8a7b 100644 --- a/docusaurus/docs/user-docs/content-type-builder/managing-content-types.md +++ b/docusaurus/docs/user-docs/content-type-builder/managing-content-types.md @@ -9,7 +9,6 @@ tags: - single type --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ScreenshotNumberReference from '/src/components/ScreenshotNumberReference.jsx'; # Managing content-types diff --git a/docusaurus/docs/user-docs/media-library/adding-assets.md b/docusaurus/docs/user-docs/media-library/adding-assets.md index bb087b269b..5297a0d0a8 100644 --- a/docusaurus/docs/user-docs/media-library/adding-assets.md +++ b/docusaurus/docs/user-docs/media-library/adding-assets.md @@ -9,8 +9,6 @@ tags: - media library --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Adding assets The Media Library displays all assets uploaded in the application, either via the [Media Library](/user-docs/media-library) or the [Content Manager](/user-docs/content-manager/writing-content.md#filling-up-fields) when managing a media field. diff --git a/docusaurus/docs/user-docs/media-library/introduction-to-the-media-library.md b/docusaurus/docs/user-docs/media-library/introduction-to-the-media-library.md index c82f0b5b73..517339897c 100644 --- a/docusaurus/docs/user-docs/media-library/introduction-to-the-media-library.md +++ b/docusaurus/docs/user-docs/media-library/introduction-to-the-media-library.md @@ -12,7 +12,6 @@ tags: pagination_next: user-docs/media-library/adding-assets --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ScreenshotNumberReference from '/src/components/ScreenshotNumberReference.jsx'; # Introduction to the Media Library diff --git a/docusaurus/docs/user-docs/media-library/managing-assets.md b/docusaurus/docs/user-docs/media-library/managing-assets.md index 76970725dc..eb5400a22c 100644 --- a/docusaurus/docs/user-docs/media-library/managing-assets.md +++ b/docusaurus/docs/user-docs/media-library/managing-assets.md @@ -9,7 +9,6 @@ tags: - media library --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ScreenshotNumberReference from '/src/components/ScreenshotNumberReference.jsx'; # Managing individual assets diff --git a/docusaurus/docs/user-docs/media-library/organizing-assets-with-folders.md b/docusaurus/docs/user-docs/media-library/organizing-assets-with-folders.md index f3e548c9f7..3b7e6e4c8f 100644 --- a/docusaurus/docs/user-docs/media-library/organizing-assets-with-folders.md +++ b/docusaurus/docs/user-docs/media-library/organizing-assets-with-folders.md @@ -10,7 +10,6 @@ tags: - Users, Roles & Permissions --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ScreenshotNumberReference from '/src/components/ScreenshotNumberReference.jsx'; # Organizing assets with folders diff --git a/docusaurus/docs/user-docs/plugins/installing-plugins-via-marketplace.md b/docusaurus/docs/user-docs/plugins/installing-plugins-via-marketplace.md index e25510e988..6877b4b690 100644 --- a/docusaurus/docs/user-docs/plugins/installing-plugins-via-marketplace.md +++ b/docusaurus/docs/user-docs/plugins/installing-plugins-via-marketplace.md @@ -9,12 +9,8 @@ tags: - upload plugin --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Using the Marketplace - - The Marketplace is where users can find additional plugins to customize Strapi applications, and additional [providers](/user-docs/plugins#providers/) to extend plugins. The Marketplace is located in the admin panel, indicated by ![Marketplace icon](/img/assets/icons/v5/ShoppingCart.svg) _Marketplace_. In the Marketplace, users can browse or search for plugins and providers, link to detailed descriptions for each, and submit new plugins and providers. :::note strapi In-app Marketplace vs. Market website diff --git a/docusaurus/docs/user-docs/plugins/introduction-to-plugins.md b/docusaurus/docs/user-docs/plugins/introduction-to-plugins.md index df8f00e3e1..75d4e3e8e5 100644 --- a/docusaurus/docs/user-docs/plugins/introduction-to-plugins.md +++ b/docusaurus/docs/user-docs/plugins/introduction-to-plugins.md @@ -12,8 +12,6 @@ tags: pagination_next: user-docs/plugins/installing-plugins-via-marketplace --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Introduction to plugins Strapi is built around different types of plugins. Every default Strapi application comes with the following pre-installed plugins: diff --git a/docusaurus/docs/user-docs/plugins/strapi-plugins.md b/docusaurus/docs/user-docs/plugins/strapi-plugins.md index 58a21055a3..677e474aa9 100644 --- a/docusaurus/docs/user-docs/plugins/strapi-plugins.md +++ b/docusaurus/docs/user-docs/plugins/strapi-plugins.md @@ -13,8 +13,6 @@ tags: - Strapi plugin --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # List of Strapi plugins Strapi builds and maintains plugins that extend the functionality of a core Strapi application. This section is a reference guide to the pre-installed plugins and additional plugins developed by Strapi, which are available in the [Marketplace](/user-docs/plugins/installing-plugins-via-marketplace/). Additional documentation on plugins is provided in the relevant sections of the User Guide and the Developer Documentation, however, a brief plugin description, how the installed plugin works, and changes to the admin panel is provided. diff --git a/docusaurus/docs/user-docs/releases/creating-a-release.md b/docusaurus/docs/user-docs/releases/creating-a-release.md index 0b7553fd5b..715e93a301 100644 --- a/docusaurus/docs/user-docs/releases/creating-a-release.md +++ b/docusaurus/docs/user-docs/releases/creating-a-release.md @@ -8,8 +8,6 @@ tags: - Strapi Cloud --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Creating a release The ![Releases icon](/img/assets/icons/v5/PaperPlane.svg) [Releases](/user-docs/releases/introduction) page allows creating new releases that will be used to organize entries. diff --git a/docusaurus/docs/user-docs/releases/managing-a-release.md b/docusaurus/docs/user-docs/releases/managing-a-release.md index 306fb64739..6a25bfc18f 100644 --- a/docusaurus/docs/user-docs/releases/managing-a-release.md +++ b/docusaurus/docs/user-docs/releases/managing-a-release.md @@ -25,11 +25,12 @@ Adding entries to a [release](/user-docs/releases/introduction) allow viewing th From a release page, you can: - edit the release, to update its name or schedule it, or delete the release, - - decide whether an entry will be published or unpublished with the release, - - and publish the release. + + + :::caution Since publishing an entry with a release means turning a draft entry into a published entry, Releases will not work if [Draft & Publish](/user-docs/content-manager/saving-and-publishing-content) is disabled for the content-type. ::: @@ -85,8 +86,10 @@ Publishing a release means that all the actions (publish or unpublish) defined f The _Status_ column displays the status of each entry: - ![Success icon](/img/assets/icons/v5/CheckCircle.svg) Already published: the entry is already published and publishing the release will not affect this entry + - ![Success icon](/img/assets/icons/v5/CheckCircle.svg) Already unpublished: the entry is already unpublished, and publishing the release will not affect this entry. - ![Success icon](/img/assets/icons/v5/CheckCircle.svg) Ready to publish: the entry is ready to be published with the release - - ![Fail icon](/img/assets/icons/v5/CrossCircle2.svg) "[field name] is required", "[field name] is too short" or "[field name] is too long": the entry cannot be published because of the issue stated in the red warning message. In this case, the release will be indicated as *Blocked* until all issues have been fixed. + - ![Success icon](/img/assets/icons/v5/CheckCircle.svg) Ready to unpublish: the entry is ready to be unpublished with the release + - ![Fail icon](/img/assets/icons/v5/CrossCircle2.svg) Not ready to publish: the entry cannot be published because some fields are incorrectly filled, or it hasn't reached the required stage for publishing. In this case, the release will be indicated as *Blocked* until all issues have been fixed. If some of your entries have a ![Fail icon](/img/assets/icons/v5/CrossCircle2.svg) status, click the ![More icon](/img/assets/icons/v5/More.svg) and the **Edit the entry** button to fix the issues until all entries have the ![Success icon](/img/assets/icons/v5/CheckCircle.svg) status. Note that you will have to click on the **Refresh** button to update the release page as you fix the various entries issues. diff --git a/docusaurus/docs/user-docs/settings/API-tokens.md b/docusaurus/docs/user-docs/settings/API-tokens.md index dc010bdc98..c103b5ec1b 100644 --- a/docusaurus/docs/user-docs/settings/API-tokens.md +++ b/docusaurus/docs/user-docs/settings/API-tokens.md @@ -7,8 +7,6 @@ tags: - GraphQL API --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Managing API tokens :::prerequisites diff --git a/docusaurus/docs/user-docs/settings/admin-panel.md b/docusaurus/docs/user-docs/settings/admin-panel.md index adc164df9f..8b4e9154bb 100644 --- a/docusaurus/docs/user-docs/settings/admin-panel.md +++ b/docusaurus/docs/user-docs/settings/admin-panel.md @@ -6,8 +6,6 @@ tags: - company logo --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Customizing the logo The default Strapi logos, displayed in the main navigation of a Strapi application and the authentication pages, can be modified from ![Settings icon](/img/assets/icons/v5/Cog.svg) *Settings > Global settings > Overview*. diff --git a/docusaurus/docs/user-docs/settings/audit-logs.md b/docusaurus/docs/user-docs/settings/audit-logs.md index d5c7a9cd67..2abbfbcb9f 100644 --- a/docusaurus/docs/user-docs/settings/audit-logs.md +++ b/docusaurus/docs/user-docs/settings/audit-logs.md @@ -10,8 +10,6 @@ tags: - Strapi Cloud --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Audit Logs The **Audit Logs** section provides a searchable and filterable display of all activities performed by users of the Strapi application. diff --git a/docusaurus/docs/user-docs/settings/configuring-users-permissions-plugin-settings.md b/docusaurus/docs/user-docs/settings/configuring-users-permissions-plugin-settings.md index f827226bfa..bc8416ac7d 100644 --- a/docusaurus/docs/user-docs/settings/configuring-users-permissions-plugin-settings.md +++ b/docusaurus/docs/user-docs/settings/configuring-users-permissions-plugin-settings.md @@ -7,8 +7,6 @@ tags: - Users, Roles & Permissions --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Configuring Users & Permissions plugin settings The Users & Permissions plugin is managed from the *Users & Permissions plugin* settings section, accessible from ![Settings icon](/img/assets/icons/v5/Cog.svg) *Settings* in the main navigation of the admin panel. This settings section allows to configure the available providers, email templates and the advanced settings of the plugin. It also allows to define the end-users roles and their related permissions (see [Configuring end-user roles](../users-roles-permissions/configuring-end-users-roles.md)). diff --git a/docusaurus/docs/user-docs/settings/internationalization.md b/docusaurus/docs/user-docs/settings/internationalization.md index 98be10983b..c6bce974d5 100644 --- a/docusaurus/docs/user-docs/settings/internationalization.md +++ b/docusaurus/docs/user-docs/settings/internationalization.md @@ -7,8 +7,6 @@ tags: - plugins --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Configuring Internationalization locales The [Internationalization plugin](/user-docs/plugins/strapi-plugins.md#-internationalization-plugin) allows to manage content in different languages, called "locales". Once the Internationalization plugin is installed in a Strapi application (see [Installing plugins via the Marketplace](/user-docs/plugins/installing-plugins-via-marketplace.md)), administrators can manage locales from ![Settings icon](/img/assets/icons/v5/Cog.svg) *Settings > Global settings > Internationalization*. diff --git a/docusaurus/docs/user-docs/settings/media-library-settings.md b/docusaurus/docs/user-docs/settings/media-library-settings.md index 40410d69b7..dee3e88eca 100644 --- a/docusaurus/docs/user-docs/settings/media-library-settings.md +++ b/docusaurus/docs/user-docs/settings/media-library-settings.md @@ -7,8 +7,6 @@ tags: - plugins --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Configuring the Media Library The [Media Library](/user-docs/media-library) displays all assets uploaded in the Strapi application. The Media Library settings allow controlling the format, file size, and orientation of uploaded assets. Those settings can be configured from ![Settings icon](/img/assets/icons/v5/Cog.svg) *Settings > Global settings > Media Library*. diff --git a/docusaurus/docs/user-docs/settings/review-workflows.md b/docusaurus/docs/user-docs/settings/review-workflows.md index 52e313b922..f9fab7e8f8 100644 --- a/docusaurus/docs/user-docs/settings/review-workflows.md +++ b/docusaurus/docs/user-docs/settings/review-workflows.md @@ -8,8 +8,6 @@ tags: - Strapi Cloud --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Managing Review Workflows The Review Workflows feature allows you to create and manage workflows for your various content-types. Each workflow can consist of any review stages for your content, enabling your team to collaborate in the content creation flow from draft to publication. @@ -24,7 +22,7 @@ The Review Workflows feature allows you to create and manage workflows for your In many organizations different teams review different parts of content. By using different review workflows for different content-types, it is possible to adjust each workflow to the needs of each team involved. -The default workflow is configured to have 4 stages: To do, In progress, Ready to review, and Reviewed. All 4 stages can be edited, reordered or deleted as needed, and it is also possible to add new stages. +The default workflow is configured to have 4 stages: To do, In progress, Ready to review, and Reviewed. All 4 stages can be edited, reordered or deleted as needed, and it is also possible to add new stages. Additionally, any stage can be defined as a required stage for publishing, ensuring content must pass through that stage before it can be published. Before being available in the [Content Manager](/user-docs/content-manager/reviewing-content), review workflows must be configured from ![Settings icon](/img/assets/icons/v5/Cog.svg) *Settings > Global settings > Review Workflows*. The Review workflows settings are only available to users with the Super Admin role by default. Other roles must be granted the **Review workflows** permissions. See [Users, Roles, & Permissions](/user-docs/users-roles-permissions) for more information. @@ -46,6 +44,7 @@ Before being available in the [Content Manager](/user-docs/content-manager/revie | Workflow name | Write a unique name of workflow. | | Associated to | (optional) Assign this workflow to one or more existing content-types. | | Stages | Add review stages (see [Adding a new stage](#adding-a-new-stage)). | + | Required stage | Define any stage as required for publishing. | 3. Click on the **Save** button. The new workflow will be displayed in the list-view and for every content-type assigned. diff --git a/docusaurus/docs/user-docs/settings/single-sign-on.md b/docusaurus/docs/user-docs/settings/single-sign-on.md index e9516d454b..92dc05eab5 100644 --- a/docusaurus/docs/user-docs/settings/single-sign-on.md +++ b/docusaurus/docs/user-docs/settings/single-sign-on.md @@ -7,8 +7,6 @@ tags: - Single Sign-On (SSO) --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Configuring Single Sign-On (SSO) Single Sign-On (SSO) can be made available on a Strapi application to allow administrators to authenticate through an identity provider (e.g. Microsoft Azure Active Directory). SSO configurations can be done from ![Settings icon](/img/assets/icons/v5/Cog.svg) *Settings > Global settings > Single Sign-On*. diff --git a/docusaurus/docs/user-docs/settings/transfer-tokens.md b/docusaurus/docs/user-docs/settings/transfer-tokens.md index 3005e6788a..561e55330d 100644 --- a/docusaurus/docs/user-docs/settings/transfer-tokens.md +++ b/docusaurus/docs/user-docs/settings/transfer-tokens.md @@ -7,8 +7,6 @@ tags: - transfer tokens --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Managing transfer tokens :::prerequisites diff --git a/docusaurus/docs/user-docs/users-roles-permissions/configuring-administrator-roles.md b/docusaurus/docs/user-docs/users-roles-permissions/configuring-administrator-roles.md index 4fb2738643..827d2ec678 100644 --- a/docusaurus/docs/user-docs/users-roles-permissions/configuring-administrator-roles.md +++ b/docusaurus/docs/user-docs/users-roles-permissions/configuring-administrator-roles.md @@ -4,8 +4,6 @@ displayed_sidebar: userDocsSidebar sidebar_position: 2 --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Configuring administrator roles (RBAC) Administrators are the users of an admin panel of a Strapi application. Administrator accounts and roles are managed with the Role-Based Access Control (RBAC) feature. It is available in the *Administration panel* section of the ![Settings icon](/img/assets/icons/v5/Cog.svg) *Settings* sub navigation. diff --git a/docusaurus/docs/user-docs/users-roles-permissions/configuring-end-users-roles.md b/docusaurus/docs/user-docs/users-roles-permissions/configuring-end-users-roles.md index e313aa8449..e260c6ebf2 100644 --- a/docusaurus/docs/user-docs/users-roles-permissions/configuring-end-users-roles.md +++ b/docusaurus/docs/user-docs/users-roles-permissions/configuring-end-users-roles.md @@ -5,8 +5,6 @@ displayed_sidebar: userDocsSidebar sidebar_position: 4 --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Configuring end-user roles End-users are the users who consume the content that is created and managed with a Strapi application and displayed on front-end applications (e.g. websites, mobile applications, connected devices etc.). Unlike the administrators, they do not have access to the admin panel. diff --git a/docusaurus/docs/user-docs/users-roles-permissions/managing-administrators.md b/docusaurus/docs/user-docs/users-roles-permissions/managing-administrators.md index 25819554ab..fddba5c4a7 100644 --- a/docusaurus/docs/user-docs/users-roles-permissions/managing-administrators.md +++ b/docusaurus/docs/user-docs/users-roles-permissions/managing-administrators.md @@ -4,7 +4,6 @@ displayed_sidebar: userDocsSidebar sidebar_position: 3 --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' import ScreenshotNumberReference from '/src/components/ScreenshotNumberReference.jsx'; # Managing administrator accounts diff --git a/docusaurus/docs/user-docs/users-roles-permissions/managing-end-users.md b/docusaurus/docs/user-docs/users-roles-permissions/managing-end-users.md index 7dc1fdc854..79d18898ed 100644 --- a/docusaurus/docs/user-docs/users-roles-permissions/managing-end-users.md +++ b/docusaurus/docs/user-docs/users-roles-permissions/managing-end-users.md @@ -5,8 +5,6 @@ displayed_sidebar: userDocsSidebar sidebar_position: 5 --- -import NotV5 from '/docs/snippets/_not-updated-to-v5.md' - # Managing end-user accounts End-users are the users who consume the content that is created and managed with a Strapi application and displayed on front-end applications (e.g. websites, mobile applications, connected devices etc.). Unlike the administrators, they do not have access to the admin panel. diff --git a/docusaurus/docusaurus.config.js b/docusaurus/docusaurus.config.js index 445f31c903..6bbdc724a2 100644 --- a/docusaurus/docusaurus.config.js +++ b/docusaurus/docusaurus.config.js @@ -64,6 +64,10 @@ const config = { type: 'module', async: true, }, + { + src: '/js/ext-signals.js', + async: true, + }, { /** * Kapa AI widget script and parameters @@ -152,7 +156,7 @@ const config = { algolia: { appId: '392RJ63O14', apiKey: 'ed62374a794e8da5accb298e13618614', - indexName: 'strapiDocsv5beta', + indexName: 'strapiDocsNextstrapiDocsNext', }, navbar: { hideOnScroll: false, diff --git a/docusaurus/package.json b/docusaurus/package.json index b7e135c03b..d6adfa8e4a 100644 --- a/docusaurus/package.json +++ b/docusaurus/package.json @@ -1,6 +1,6 @@ { "name": "strapi-docs", - "version": "5.1.0", + "version": "5.2.1", "private": true, "scripts": { "docusaurus": "docusaurus", @@ -51,6 +51,6 @@ ] }, "engines": { - "node": ">=16.14 <20" + "node": ">=16.14 <=20" } } diff --git a/docusaurus/release-notes-script.sh b/docusaurus/release-notes-script.sh new file mode 100755 index 0000000000..4079c8e56f --- /dev/null +++ b/docusaurus/release-notes-script.sh @@ -0,0 +1,325 @@ +#!/bin/bash + +# Terminal colors +RED='\033[0;31m' +GREEN='\033[0;32m' +BLUE='\033[0;34m' +NC='\033[0m' + +REPO="strapi/documentation" +OUTPUT_DIR="docs" +OUTPUT_FILE="$OUTPUT_DIR/temp-new-release-notes.md" +TEMP_DIR="/tmp/release-notes-$$" + +# Create temporary directory at the start +mkdir -p "$TEMP_DIR" + +# Make sure to clean up temp directory on exit +trap 'rm -rf "$TEMP_DIR"' EXIT + +# GitHub Configuration +setup_github_auth() { + if [ -z "$GITHUB_TOKEN" ]; then + if [ -f ~/.github_token ]; then + GITHUB_TOKEN=$(cat ~/.github_token) + else + echo -e "${BLUE}No GitHub token found.${NC}" + echo -e "Please create a token at https://github.com/settings/tokens" + echo -n "Enter your GitHub token: " + read -r GITHUB_TOKEN + echo -n "Do you want to save this token for later use? (y/N) " + read -r save_token + if [[ "$save_token" =~ ^[Yy]$ ]]; then + echo "$GITHUB_TOKEN" > ~/.github_token + chmod 600 ~/.github_token + echo -e "${GREEN}Token saved in ~/.github_token${NC}" + fi + fi + fi +} + +# Function to make GitHub API requests +gh_api_get() { + local endpoint="$1" + curl -s -H "Authorization: token $GITHUB_TOKEN" \ + -H "Accept: application/vnd.github.v3+json" \ + "https://api.github.com/repos/$REPO/$endpoint" +} + +# Function to restore terminal to a sane state +restore_terminal() { + printf "\033[?25h" # Show cursor + stty sane # Restore terminal to normal state + printf "\033[H\033[2J" # Clear screen +} + +# Function to select a milestone +select_milestone() { + # Ensure terminal is in a normal state for initial question + restore_terminal + + # Ask about including closed milestones + milestone_state="open" # Default to open + echo -e "Do you want to include closed milestones?\n(Type 'y' for 'yes', 'n' for 'no', then press Enter. Defaults to no.)" + read -r include_closed + # Only change if explicitly answered yes + if [[ "$include_closed" =~ ^[Yy]$ ]]; then + milestone_state="all" + fi + + echo -e "${BLUE}Fetching milestones...${NC}" + milestones=$(gh_api_get "milestones?state=$milestone_state&sort=created&direction=desc") + + # Check if milestones is empty or invalid + if [ -z "$milestones" ]; then + echo -e "${RED}Error fetching milestones${NC}" + exit 1 + fi + + # More robust length check + milestone_count=$(echo "$milestones" | jq '. | length' 2>/dev/null) + if [ -z "$milestone_count" ] || [ "$milestone_count" = "null" ] || [ "$milestone_count" -eq 0 ]; then + echo -e "${RED}No milestones found${NC}" + exit 1 + fi + + # Create temporary file with milestone options + echo "$milestones" | jq -r '.[] | "\(.number)) \(.title)"' > "$TEMP_DIR/milestones.txt" + + # Read options into array + local options=() + while IFS= read -r line; do + options+=("$line") + done < "$TEMP_DIR/milestones.txt" + + local total=${#options[@]} + + if [ $total -eq 0 ]; then + echo -e "${RED}No options available${NC}" + return 1 + fi + + # Save terminal state and setup cleanup + saved_tty="$(stty -g 2>/dev/null)" + + cleanup_terminal() { + printf "\033[?25h" # Show cursor + if [ -n "$saved_tty" ]; then + stty "$saved_tty" 2>/dev/null + fi + } + + trap cleanup_terminal EXIT INT TERM + + # Prepare terminal for interactive selection + printf "\033[?25l" # Hide cursor + stty raw -echo 2>/dev/null + + # Initialize selection + local selected=0 + + # Main selection loop + while true; do + # Clear screen and display header + printf "\033[H\033[2J" # Move to top and clear screen + printf "Use arrows to select a milestone (Enter to confirm, 'q' to quit):\n\n" + + # Display all options with absolute positioning + for ((i=0; i %s${NC}" "${options[$i]}" + else + printf " %s" "${options[$i]}" + fi + done + + # Read user input + IFS= read -r -n1 input + + case "$input" in + $'\x1b') # ESC sequence + read -r -n2 seq + case "$seq" in + '[A') # Up arrow + if [ $selected -gt 0 ]; then + ((selected--)) + fi + ;; + '[B') # Down arrow + if [ $selected -lt $((total - 1)) ]; then + ((selected++)) + fi + ;; + esac + ;; + ''|$'\x0a') # Enter + cleanup_terminal + printf "\033[H\033[2J" # Clear screen + SELECTED_OPTION="${options[$selected]}" + MILESTONE=$(echo "${SELECTED_OPTION}" | cut -d')' -f1) + MILESTONE_TITLE=$(echo "$milestones" | jq -r ".[] | select(.number==$MILESTONE) | .title") + printf "${GREEN}Selected: %s${NC}\n" "$SELECTED_OPTION" + return 0 + ;; + 'q'|$'\x03') # q or Ctrl-C + cleanup_terminal + printf "\033[H\033[2J" # Clear screen + printf "Selection cancelled\n" + return 1 + ;; + esac + done +} + +# Main function +main() { + # Check if docs/ directory exists + if [ ! -d "$OUTPUT_DIR" ]; then + echo -e "${RED}Directory $OUTPUT_DIR does not exist. Creating...${NC}" + mkdir -p "$OUTPUT_DIR" + fi + + setup_github_auth + select_milestone + + if [ $? -ne 0 ]; then + restore_terminal + exit 1 + fi + + echo -e "${BLUE}Generating release notes for milestone $MILESTONE_TITLE...${NC}" + + # Initialize file + rm -f "$OUTPUT_FILE" + echo "## $MILESTONE_TITLE" > "$OUTPUT_FILE" + + # Fetch PRs + prs=$(gh_api_get "issues?milestone=$MILESTONE&state=closed&pull_request") + + # Process each PR + echo "$prs" | jq -c '.[]' | while read -r pr; do + title=$(echo "$pr" | jq -r '.title') + url=$(echo "$pr" | jq -r '.html_url') + labels=$(echo "$pr" | jq -r '.labels[].name') + user=$(echo "$pr" | jq -r '.user.login') + avatar_url=$(echo "$pr" | jq -r '.user.avatar_url') + + pr_entry="- [$title]($url)" + + # Determine section + section="" + if echo "$labels" | grep -q "pr: new content"; then + section="new_content" + elif echo "$labels" | grep -q "pr: updated content"; then + section="updated_content" + elif echo "$labels" | grep -q "pr: fix\|pr: chore"; then + section="chore" + fi + + # If a section was identified + if [ -n "$section" ]; then + # Determine source + source="repo" + if echo "$labels" | grep -q "source: Dev Docs"; then + source="dev_docs" + elif echo "$labels" | grep -q "source: User Guide"; then + source="user_guide" + elif echo "$labels" | grep -q "source: Strapi Cloud"; then + source="cloud" + fi + + # Create section file if it doesn't exist + case "$section" in + "new_content") + echo "### ✨ New content" > "$TEMP_DIR/${section}_header" + ;; + "updated_content") + echo "### 🖌 Updated content" > "$TEMP_DIR/${section}_header" + ;; + "chore") + echo "### 🧹 Chore, fixes, typos, and other improvements" > "$TEMP_DIR/${section}_header" + ;; + esac + + # Create source file if it doesn't exist + case "$source" in + "dev_docs") + echo "#### Dev Docs" > "$TEMP_DIR/${section}_${source}_header" + ;; + "user_guide") + echo "#### User Guide" > "$TEMP_DIR/${section}_${source}_header" + ;; + "cloud") + echo "#### Strapi Cloud" > "$TEMP_DIR/${section}_${source}_header" + ;; + "repo") + echo "#### Repository" > "$TEMP_DIR/${section}_${source}_header" + ;; + esac + + # Add entry + echo "$pr_entry" >> "$TEMP_DIR/${section}_${source}_content" + fi + + # Save contributor information + echo "$user|$avatar_url" >> "$TEMP_DIR/contributors_raw" + done + + # Assemble final file + first_section=true + for section in "new_content" "updated_content" "chore"; do + has_content=false + + # Check if we have content for this section + for source in "dev_docs" "user_guide" "cloud" "repo"; do + if [ -f "$TEMP_DIR/${section}_${source}_content" ] && [ -s "$TEMP_DIR/${section}_${source}_content" ]; then + has_content=true + break + fi + done + + # If we have content, add the section and its subsections + if [ "$has_content" = true ]; then + if [ "$first_section" = true ]; then + first_section=false + else + echo "" >> "$OUTPUT_FILE" + fi + + cat "$TEMP_DIR/${section}_header" >> "$OUTPUT_FILE" + + first_subsection=true + for source in "dev_docs" "user_guide" "cloud" "repo"; do + if [ -f "$TEMP_DIR/${section}_${source}_content" ] && [ -s "$TEMP_DIR/${section}_${source}_content" ]; then + echo "" >> "$OUTPUT_FILE" + cat "$TEMP_DIR/${section}_${source}_header" >> "$OUTPUT_FILE" + cat "$TEMP_DIR/${section}_${source}_content" >> "$OUTPUT_FILE" + fi + done + fi + done + + # Add contributors if any + if [ -f "$TEMP_DIR/contributors_raw" ] && [ -s "$TEMP_DIR/contributors_raw" ]; then + echo -e "\n***" >> "$OUTPUT_FILE" + echo "This release was made possible thanks to the following contributors. Thank you! 🫶" >> "$OUTPUT_FILE" + echo "
" >> "$OUTPUT_FILE" + + # Sort and deduplicate contributors + sort -u "$TEMP_DIR/contributors_raw" | while IFS='|' read -r user avatar_url; do + cat >> "$OUTPUT_FILE" << EOF + + $user + +EOF + done + + echo "
" >> "$OUTPUT_FILE" + echo -e "
\n
" >> "$OUTPUT_FILE" + fi + + echo -e "${GREEN}Release notes generated in $OUTPUT_FILE${NC}" +} + +main diff --git a/docusaurus/sidebars.js b/docusaurus/sidebars.js index f98da6cdc5..0db7c4bd19 100644 --- a/docusaurus/sidebars.js +++ b/docusaurus/sidebars.js @@ -15,40 +15,33 @@ /** @type {import('@docusaurus/plugin-content-docs').SidebarsConfig} */ const sidebars = { devDocsSidebar: [ - { // Getting Started + { + // Getting Started type: 'category', collapsed: false, label: '🚀 Getting Started', - link: {type: 'doc', id: 'dev-docs/intro'}, + link: { type: 'doc', id: 'dev-docs/intro' }, items: [ { type: 'doc', id: 'dev-docs/intro', - customProps: { - updated: true, - }, }, { type: 'doc', id: 'dev-docs/quick-start', - customProps: { - updated: true, - }, }, { type: 'doc', id: 'dev-docs/whats-new', label: "What's new?", - customProps: { - udpated: true - } }, 'dev-docs/faq', 'dev-docs/community', 'dev-docs/usage-information', - ] + ], }, - { // Setup & Deployment + { + // Setup & Deployment type: 'category', collapsed: false, label: '⚙️ Setup & Deployment', @@ -65,10 +58,7 @@ const sidebars = { { type: 'category', label: 'Installation', - link: {type: 'doc', id: 'dev-docs/installation'}, - customProps: { - updated: true, - }, + link: { type: 'doc', id: 'dev-docs/installation' }, items: [ { type: 'doc', @@ -78,12 +68,9 @@ const sidebars = { { type: 'doc', id: 'dev-docs/installation/cli', - customProps: { - updated: true, - }, }, 'dev-docs/installation/docker', - ] + ], }, 'dev-docs/project-structure', { @@ -95,7 +82,13 @@ const sidebars = { label: 'Introduction to configuration', id: 'dev-docs/configurations', }, - 'dev-docs/configurations/database', + { + type: 'doc', + id: 'dev-docs/configurations/database', + customProps: { + updated: true, + }, + }, 'dev-docs/configurations/server', 'dev-docs/configurations/admin-panel', 'dev-docs/configurations/middlewares', @@ -123,7 +116,7 @@ const sidebars = { id: 'dev-docs/deployment', }, items: [ - { + { type: 'doc', label: 'Introduction to deployment', id: 'dev-docs/deployment', @@ -133,33 +126,28 @@ const sidebars = { label: '☁️ Strapi Cloud', id: 'cloud/getting-started/deployment', }, - ] - } - ] + ], + }, + ], }, - { // Content APIs + { + // Content APIs type: 'category', collapsed: false, label: '📦 Content API', - link: {type: 'doc', id: 'dev-docs/api/content-api'}, + link: { type: 'doc', id: 'dev-docs/api/content-api' }, items: [ { type: 'doc', label: 'APIs Introduction & Concepts', id: 'dev-docs/api/content-api', - customProps: { - updated: true, - }, }, { type: 'category', label: 'REST API', - customProps: { - updated: true, - }, link: { type: 'doc', - id: 'dev-docs/api/rest' + id: 'dev-docs/api/rest', }, items: [ { @@ -174,14 +162,11 @@ const sidebars = { 'dev-docs/api/rest/relations', 'dev-docs/api/rest/interactive-query-builder', 'dev-docs/api/rest/guides/intro', - ] + ], }, { type: 'doc', id: 'dev-docs/api/graphql', - customProps: { - updated: true, - }, }, // { // type: 'category', @@ -222,105 +207,120 @@ const sidebars = { label: 'Document Service API', link: { type: 'doc', - id: 'dev-docs/api/document-service' - }, - customProps: { - new: true + id: 'dev-docs/api/document-service', }, items: [ { type: 'doc', label: 'Introduction & Concepts', - id: 'dev-docs/api/document' + id: 'dev-docs/api/document', }, { type: 'doc', label: 'Available methods', - id: 'dev-docs/api/document-service' + id: 'dev-docs/api/document-service', }, { type: 'doc', label: 'Filters', - id: 'dev-docs/api/document-service/filters' + id: 'dev-docs/api/document-service/filters', }, { type: 'doc', label: 'Populate', - id: 'dev-docs/api/document-service/populate' + id: 'dev-docs/api/document-service/populate', }, { type: 'doc', label: 'Fields', - id: 'dev-docs/api/document-service/fields' + id: 'dev-docs/api/document-service/fields', }, { type: 'doc', label: 'Sort & Pagination', - id: 'dev-docs/api/document-service/sort-pagination' + id: 'dev-docs/api/document-service/sort-pagination', }, { type: 'doc', label: 'Locale', - id: 'dev-docs/api/document-service/locale' + id: 'dev-docs/api/document-service/locale', }, { type: 'doc', label: 'Status', - id: 'dev-docs/api/document-service/status' + id: 'dev-docs/api/document-service/status', + customProps: { + updated: true, + }, }, { type: 'doc', label: 'Middlewares', - id: 'dev-docs/api/document-service/middlewares' + id: 'dev-docs/api/document-service/middlewares', }, - ] + ], }, - ] + ], }, - { // Advanced features + { + // Advanced features type: 'category', label: '🔧 Advanced features', collapsed: false, link: { type: 'doc', - id: 'dev-docs/advanced-features' + id: 'dev-docs/advanced-features', }, items: [ { type: 'doc', label: 'Introduction to advanced features', id: 'dev-docs/advanced-features', - customProps: { - new: true, - }, }, { type: 'doc', label: 'Internationalization (i18n)', - customProps: { - updated: true, - }, id: 'dev-docs/i18n', }, { type: 'doc', id: 'dev-docs/cli', - customProps: { - updated: true, - }, }, { type: 'category', label: 'TypeScript', link: { type: 'doc', - id: 'dev-docs/typescript' + id: 'dev-docs/typescript', }, items: [ 'dev-docs/typescript', - 'dev-docs/typescript/development', + { + type: 'doc', + id: 'dev-docs/typescript/development', + customProps: { + updated: true, + }, + }, 'dev-docs/typescript/adding-support-to-existing-project', - ] + { + type: 'category', + label: 'Guides', + link: { + type: 'doc', + id: 'dev-docs/typescript/development/guides', + }, + items: [ + { + type: 'doc', + id: 'dev-docs/typescript/development/guides/documents-and-entries', + customProps: { + new: true, + }, + }, + ], + }, + ], }, { type: 'doc', @@ -331,9 +331,6 @@ const sidebars = { type: 'doc', label: 'Templates', id: 'dev-docs/templates', - customProps: { - updated: true, - } }, { type: 'category', @@ -354,16 +351,17 @@ const sidebars = { type: 'doc', label: 'Data transfer', id: 'dev-docs/data-management/transfer', - } + }, ], }, 'dev-docs/database-migrations', 'dev-docs/database-transactions', 'dev-docs/testing', 'dev-docs/error-handling', - ] + ], }, - { // Customization + { + // Customization type: 'category', collapsed: false, label: '🛠 Customization', @@ -376,19 +374,13 @@ const sidebars = { type: 'doc', label: 'Customization Introduction & Concepts', id: 'dev-docs/customization', - customProps: { - new: true, - }, }, { type: 'category', label: 'Back-end customization', - customProps: { - updated: true, - }, link: { type: 'doc', - id: 'dev-docs/backend-customization' + id: 'dev-docs/backend-customization', }, items: [ { @@ -407,14 +399,11 @@ const sidebars = { 'dev-docs/backend-customization/services', 'dev-docs/backend-customization/models', 'dev-docs/backend-customization/webhooks', - ] + ], }, { type: 'category', label: 'Admin panel customization', - customProps: { - updated: true, - }, link: { type: 'doc', id: 'dev-docs/admin-panel-customization', @@ -431,11 +420,12 @@ const sidebars = { 'dev-docs/admin-panel-customization/wysiwyg-editor', 'dev-docs/admin-panel-customization/extension', 'dev-docs/admin-panel-customization/deployment', - ] + ], }, - ] + ], }, - { // Plugins + { + // Plugins type: 'category', collapsed: false, label: '🔌 Plugins', @@ -447,20 +437,20 @@ const sidebars = { { type: 'doc', label: 'Plugins Introduction & Concepts', - id: 'dev-docs/plugins' + id: 'dev-docs/plugins', }, { type: 'category', label: 'Using plugins', link: { type: 'doc', - id: 'dev-docs/plugins/using-plugins' + id: 'dev-docs/plugins/using-plugins', }, items: [ { type: 'doc', label: 'Introduction to using plugins', - id: 'dev-docs/plugins/using-plugins' + id: 'dev-docs/plugins/using-plugins', }, { type: 'doc', @@ -493,14 +483,11 @@ const sidebars = { label: 'Users & Permissions', id: 'dev-docs/plugins/users-permissions', }, - ] + ], }, { type: 'category', label: 'Developing plugins', - customProps: { - updated: true, - }, link: { type: 'doc', id: 'dev-docs/plugins/developing-plugins', @@ -509,24 +496,18 @@ const sidebars = { { type: 'doc', label: 'Introduction to developing plugins', - id: 'dev-docs/plugins/developing-plugins' + id: 'dev-docs/plugins/developing-plugins', }, 'dev-docs/plugins/development/create-a-plugin', { type: 'doc', id: 'dev-docs/plugins/development/plugin-structure', label: 'Plugin structure', - customProps: { - updated: true, - }, }, { type: 'doc', id: 'dev-docs/plugins/development/plugin-sdk', label: 'Plugin SDK', - customProps: { - new: true, - }, }, { type: 'category', @@ -540,18 +521,12 @@ const sidebars = { type: 'doc', label: 'Introduction to Admin Panel APIs', id: 'dev-docs/plugins/admin-panel-api', - customProps: { - updated: true, - }, }, { type: 'doc', id: 'dev-docs/plugins/content-manager-apis', - customProps: { - new: true, - }, - } - ] + }, + ], }, { type: 'doc', @@ -571,19 +546,17 @@ const sidebars = { 'dev-docs/plugins/guides/store-and-access-data', 'dev-docs/plugins/guides/pass-data-from-server-to-admin', 'dev-docs/plugins/development/create-a-plugin', - ] - } - ] - } - ] + ], + }, + ], + }, + ], }, - { // Update & Migration + { + // Update & Migration type: 'category', collapsed: false, label: '♻️ Upgrades', - customProps: { - new: true, - }, link: { type: 'doc', id: 'dev-docs/upgrades', @@ -603,19 +576,19 @@ const sidebars = { collapsed: false, link: { type: 'doc', - id: 'dev-docs/migration/v4-to-v5/introduction-and-faq' + id: 'dev-docs/migration/v4-to-v5/introduction-and-faq', }, label: 'Upgrade to Strapi 5', items: [ { type: 'doc', label: 'Introduction and FAQ', - id: 'dev-docs/migration/v4-to-v5/introduction-and-faq' + id: 'dev-docs/migration/v4-to-v5/introduction-and-faq', }, { type: 'doc', label: 'Step-by-step guide', - id: 'dev-docs/migration/v4-to-v5/step-by-step' + id: 'dev-docs/migration/v4-to-v5/step-by-step', }, { type: 'doc', @@ -627,8 +600,8 @@ const sidebars = { label: 'Specific resources', id: 'dev-docs/migration/v4-to-v5/additional-resources/introduction', }, - ] - } + ], + }, ], }, ], @@ -638,8 +611,8 @@ const sidebars = { collapsed: false, label: 'Getting Started', link: { - type: "doc", - id: "user-docs/intro", + type: 'doc', + id: 'user-docs/intro', }, items: [ 'user-docs/intro', @@ -652,7 +625,7 @@ const sidebars = { collapsed: false, link: { type: 'doc', - id: 'user-docs/content-manager/introduction-to-content-manager' + id: 'user-docs/content-manager/introduction-to-content-manager', }, label: 'Content Manager', items: [ @@ -662,9 +635,6 @@ const sidebars = { { type: 'doc', id: 'user-docs/content-manager/working-with-content-history', - customProps: { - new: true, - } }, 'user-docs/content-manager/managing-relational-fields', 'user-docs/content-manager/translating-content', @@ -672,9 +642,6 @@ const sidebars = { { type: 'doc', id: 'user-docs/content-manager/saving-and-publishing-content', - customProps: { - updated: true, - } }, 'user-docs/content-manager/adding-content-to-releases', ], @@ -684,43 +651,49 @@ const sidebars = { collapsed: false, label: 'Content-type Builder', link: { - type: "doc", - id: "user-docs/content-type-builder/introduction-to-content-types-builder", + type: 'doc', + id: 'user-docs/content-type-builder/introduction-to-content-types-builder', }, items: [ { type: 'autogenerated', - dirName: 'user-docs/content-type-builder' - } - ] + dirName: 'user-docs/content-type-builder', + }, + ], }, { type: 'category', collapsed: false, label: 'Media Library', link: { - type: "doc", - id: "user-docs/media-library/introduction-to-the-media-library", + type: 'doc', + id: 'user-docs/media-library/introduction-to-the-media-library', }, items: [ { type: 'autogenerated', - dirName: 'user-docs/media-library' - } - ] + dirName: 'user-docs/media-library', + }, + ], }, { - type: "category", + type: 'category', collapsed: false, - label: "Releases", + label: 'Releases', link: { - type: "doc", - id: "user-docs/releases/introduction", + type: 'doc', + id: 'user-docs/releases/introduction', }, items: [ 'user-docs/releases/introduction', 'user-docs/releases/creating-a-release', - 'user-docs/releases/managing-a-release', + { + type: 'doc', + id: 'user-docs/releases/managing-a-release', + customProps: { + updated: true, + }, + }, ], }, { @@ -728,50 +701,50 @@ const sidebars = { collapsed: false, label: 'Users, Roles & Permissions', link: { - type: "doc", - id: "user-docs/users-roles-permissions/introduction-to-users-roles-permissions", + type: 'doc', + id: 'user-docs/users-roles-permissions/introduction-to-users-roles-permissions', }, items: [ { type: 'autogenerated', - dirName: 'user-docs/users-roles-permissions' - } - ] + dirName: 'user-docs/users-roles-permissions', + }, + ], }, { type: 'category', collapsed: false, label: 'Plugins', link: { - type: "doc", - id: "user-docs/plugins/introduction-to-plugins", + type: 'doc', + id: 'user-docs/plugins/introduction-to-plugins', }, items: [ { type: 'autogenerated', - dirName: 'user-docs/plugins' - } - ] + dirName: 'user-docs/plugins', + }, + ], }, { type: 'category', collapsed: false, label: 'Settings', link: { - type: "doc", - id: "user-docs/settings/introduction", + type: 'doc', + id: 'user-docs/settings/introduction', }, items: [ - 'user-docs/settings/introduction', - 'user-docs/settings/configuring-users-permissions-plugin-settings', - 'user-docs/settings/audit-logs', + 'user-docs/settings/introduction', + 'user-docs/settings/configuring-users-permissions-plugin-settings', + 'user-docs/settings/audit-logs', { type: 'category', collapsed: false, label: 'Configuring global settings', link: { type: 'doc', - id: 'user-docs/settings/introduction' + id: 'user-docs/settings/introduction', }, items: [ 'user-docs/settings/admin-panel', @@ -783,167 +756,146 @@ const sidebars = { type: 'doc', label: 'Review Workflows', id: 'user-docs/settings/review-workflows', + customProps: { + updated: true, + }, }, 'user-docs/settings/single-sign-on', 'user-docs/settings/transfer-tokens', - ] + ], }, ], }, ], cloudSidebar: [ { - type: "category", + type: 'category', collapsed: false, - label: "Getting Started", + label: 'Getting Started', link: { - type: "doc", - id: "cloud/getting-started/intro", + type: 'doc', + id: 'cloud/getting-started/intro', }, items: [ - "cloud/getting-started/intro", + 'cloud/getting-started/intro', { - type: "doc", - label: "Cloud fundamentals", - id: "cloud/getting-started/cloud-fundamentals", - customProps: { - new: false, - }, + type: 'doc', + label: 'Cloud fundamentals', + id: 'cloud/getting-started/cloud-fundamentals', }, { - type: "category", - label: "Project deployment", - link: { type: "doc", id: "cloud/getting-started/deployment-options" }, - customProps: { - updated: false, - }, + type: 'category', + label: 'Project deployment', + link: { type: 'doc', id: 'cloud/getting-started/deployment-options' }, items: [ { - type: "doc", - id: "cloud/getting-started/deployment", - customProps: { - updated: true, - }, + type: 'doc', + id: 'cloud/getting-started/deployment', }, { - type: "doc", - id: "cloud/getting-started/deployment-cli", - customProps: { - new: true, - }, - }, + type: 'doc', + id: 'cloud/getting-started/deployment-cli', + }, ], }, { - type: "doc", - id: "cloud/getting-started/usage-billing", - customProps: { - updated: false, - }, + type: 'doc', + id: 'cloud/getting-started/usage-billing', }, - "cloud/getting-started/caching", + 'cloud/getting-started/caching', { - type: "doc", - label: "Notifications", - id: "cloud/projects/notifications", + type: 'doc', + label: 'Notifications', + id: 'cloud/projects/notifications', }, ], }, { - type: "category", + type: 'category', collapsed: false, - label: "Projects management", + label: 'Projects management', link: { - type: "doc", - id: "cloud/projects/overview", + type: 'doc', + id: 'cloud/projects/overview', }, items: [ - "cloud/projects/overview", + 'cloud/projects/overview', { - type: "doc", - label: "Project settings", - id: "cloud/projects/settings", - customProps: { - updated: true, - }, + type: 'doc', + label: 'Project settings', + id: 'cloud/projects/settings', }, - "cloud/projects/collaboration", - "cloud/projects/runtime-logs", + 'cloud/projects/collaboration', + 'cloud/projects/runtime-logs', ], }, { - type: "category", + type: 'category', collapsed: false, - label: "Deployments", + label: 'Deployments', link: { - type: "doc", - id: "cloud/projects/deploys", + type: 'doc', + id: 'cloud/projects/deploys', }, - items: ["cloud/projects/deploys", "cloud/projects/deploys-history"], + items: ['cloud/projects/deploys', 'cloud/projects/deploys-history'], }, { - type: "category", + type: 'category', collapsed: false, - label: "Account management", + label: 'Account management', link: { - type: "doc", - id: "cloud/account/account-settings", + type: 'doc', + id: 'cloud/account/account-settings', }, items: [ - "cloud/account/account-settings", + 'cloud/account/account-settings', { - type: "doc", - id: "cloud/account/account-billing", - label: "Account billing & invoices", - customProps: { - updated: false, - }, + type: 'doc', + id: 'cloud/account/account-billing', + label: 'Account billing & invoices', }, ], }, { - type: "category", + type: 'category', collapsed: false, - label: "Command Line Interface", + label: 'Command Line Interface', link: { - type: "doc", - id: "cloud/cli/cloud-cli", + type: 'doc', + id: 'cloud/cli/cloud-cli', }, items: [ { - type: "doc", - id: "cloud/cli/cloud-cli", - label: "Strapi Cloud CLI", - customProps: { - new: true, - }, + type: 'doc', + id: 'cloud/cli/cloud-cli', + label: 'Strapi Cloud CLI', }, ], }, { - type: "category", + type: 'category', collapsed: false, - label: "Advanced configuration", + label: 'Advanced configuration', link: { - type: "doc", - id: "cloud/advanced/database", + type: 'doc', + id: 'cloud/advanced/database', }, items: [ - "cloud/advanced/database", + 'cloud/advanced/database', { - type: "doc", - id: "cloud/advanced/email", - label: "Email provider", + type: 'doc', + id: 'cloud/advanced/email', + label: 'Email provider', customProps: { - new: false, + updated: true, }, }, { - type: "doc", - id: "cloud/advanced/upload", - label: "Upload provider", + type: 'doc', + id: 'cloud/advanced/upload', + label: 'Upload provider', customProps: { - new: false, + updated: true, }, }, ], @@ -953,7 +905,7 @@ const sidebars = { { type: 'link', label: '⬅️ Back to Dev Docs content', - href: '/dev-docs/intro' + href: '/dev-docs/intro', }, { type: 'category', @@ -961,13 +913,13 @@ const sidebars = { label: 'REST API reference', link: { type: 'doc', - id: 'dev-docs/api/rest' + id: 'dev-docs/api/rest', }, items: [ { type: 'category', label: 'Endpoints and basic requests', - link: {type: 'doc', id: 'dev-docs/api/rest'}, + link: { type: 'doc', id: 'dev-docs/api/rest' }, collapsed: false, items: [ { @@ -978,43 +930,43 @@ const sidebars = { { type: 'link', label: 'Get documents', - href: '/dev-docs/api/rest#get-documents' + href: '/dev-docs/api/rest#get-all', }, { type: 'link', label: 'Get a document', - href: '/dev-docs/api/rest#get-a-document' + href: '/dev-docs/api/rest#get', }, { type: 'link', label: 'Create a document', - href: '/dev-docs/api/rest#create-a-document' + href: '/dev-docs/api/rest#create', }, { type: 'link', label: 'Update a document', - href: '/dev-docs/api/rest#update-a-document' + href: '/dev-docs/api/rest#update', }, { type: 'link', label: 'Delete a document', - href: '/dev-docs/api/rest#delete-a-document' + href: '/dev-docs/api/rest#delete', }, - ] + ], }, { type: 'doc', id: 'dev-docs/api/rest/interactive-query-builder', - label: '✨ Interactive Query Builder' + label: '✨ Interactive Query Builder', }, { type: 'doc', - id: 'dev-docs/api/rest/parameters' + id: 'dev-docs/api/rest/parameters', }, { type: 'category', label: 'Populate and Select', - link: {type: 'doc', id: 'dev-docs/api/rest/populate-select'}, + link: { type: 'doc', id: 'dev-docs/api/rest/populate-select' }, collapsed: false, items: [ { @@ -1027,18 +979,21 @@ const sidebars = { label: 'Population', href: '/dev-docs/api/rest/populate-select#population', }, - ] + ], }, { type: 'category', collapsed: false, label: 'Filters, Locale, Publication State', - link: {type: 'doc', id: 'dev-docs/api/rest/filters-locale-publication' }, + link: { + type: 'doc', + id: 'dev-docs/api/rest/filters-locale-publication', + }, items: [ { type: 'link', label: 'Filtering', - href: '/dev-docs/api/rest/filters-locale-publication#filtering' + href: '/dev-docs/api/rest/filters-locale-publication#filtering', }, { type: 'link', @@ -1066,58 +1021,58 @@ const sidebars = { type: 'category', collapsed: false, label: 'Sort and Pagination', - link: { type: 'doc', id: 'dev-docs/api/rest/sort-pagination'}, + link: { type: 'doc', id: 'dev-docs/api/rest/sort-pagination' }, items: [ { type: 'link', label: 'Sorting', - href: '/dev-docs/api/rest/sort-pagination#sorting' + href: '/dev-docs/api/rest/sort-pagination#sorting', }, { type: 'link', label: 'Pagination', - href: '/dev-docs/api/rest/sort-pagination#pagination' + href: '/dev-docs/api/rest/sort-pagination#pagination', }, { type: 'link', label: 'Pagination by page', - href: '/dev-docs/api/rest/sort-pagination#pagination-by-page' + href: '/dev-docs/api/rest/sort-pagination#pagination-by-page', }, { type: 'link', label: 'Pagination by offset', - href: '/dev-docs/api/rest/sort-pagination#pagination-by-offset' + href: '/dev-docs/api/rest/sort-pagination#pagination-by-offset', }, - ] + ], }, { type: 'category', collapsed: false, label: 'Relations', - link: {type: 'doc', id: 'dev-docs/api/rest/relations'}, + link: { type: 'doc', id: 'dev-docs/api/rest/relations' }, items: [ { type: 'link', label: 'connect', - href: '/dev-docs/api/rest/relations#connect' + href: '/dev-docs/api/rest/relations#connect', }, { type: 'link', label: 'disconnect', - href: '/dev-docs/api/rest/relations#disconnect' + href: '/dev-docs/api/rest/relations#disconnect', }, { type: 'link', label: 'set', - href: '/dev-docs/api/rest/relations#set' + href: '/dev-docs/api/rest/relations#set', }, - ] + ], }, - ] + ], }, { - type: "category", - label: "Rest API guides", + type: 'category', + label: 'Rest API guides', collapsed: false, link: { type: 'doc', @@ -1125,28 +1080,28 @@ const sidebars = { }, items: [ { - type: "doc", - label: "Understanding populate", + type: 'doc', + label: 'Understanding populate', id: 'dev-docs/api/rest/guides/understanding-populate', }, { - type: "doc", - label: "How to populate creator fields", + type: 'doc', + label: 'How to populate creator fields', id: 'dev-docs/api/rest/guides/populate-creator-fields', }, { type: 'link', label: 'Additional resources', - href: '/dev-docs/api/rest/guides/intro#additional-resources' + href: '/dev-docs/api/rest/guides/intro#additional-resources', }, ], - } + }, ], devDocsConfigSidebar: [ { type: 'link', label: '⬅️ Back to Dev Docs content', - href: '/dev-docs/intro' + href: '/dev-docs/intro', }, { type: 'category', @@ -1168,7 +1123,7 @@ const sidebars = { label: 'Base configurations', link: { type: 'doc', - id: 'dev-docs/configurations' + id: 'dev-docs/configurations', }, items: [ 'dev-docs/configurations/database', @@ -1176,7 +1131,7 @@ const sidebars = { 'dev-docs/configurations/admin-panel', 'dev-docs/configurations/middlewares', 'dev-docs/configurations/api', - ] + ], }, { type: 'category', @@ -1184,7 +1139,7 @@ const sidebars = { collapsed: false, link: { type: 'doc', - id: 'dev-docs/configurations' + id: 'dev-docs/configurations', }, items: [ 'dev-docs/configurations/plugins', @@ -1195,7 +1150,7 @@ const sidebars = { 'dev-docs/configurations/environment', 'dev-docs/configurations/sso', 'dev-docs/configurations/features', - ] + ], }, { type: 'category', @@ -1203,7 +1158,7 @@ const sidebars = { collapsed: false, link: { type: 'doc', - id: 'dev-docs/configurations' + id: 'dev-docs/configurations', }, items: [ 'dev-docs/configurations/guides/rbac', @@ -1211,76 +1166,75 @@ const sidebars = { 'dev-docs/configurations/guides/access-cast-environment-variables', 'dev-docs/configurations/guides/access-configuration-values', 'dev-docs/configurations/guides/use-cron-jobs', - ] - } - ] + ], + }, + ], }, ], devDocsMigrationV5Sidebar: [ { type: 'link', label: '⬅️ Back to Dev Docs content', - href: '/dev-docs/intro' + href: '/dev-docs/intro', }, { type: 'category', collapsed: false, link: { type: 'doc', - id: 'dev-docs/migration/v4-to-v5/introduction-and-faq' + id: 'dev-docs/migration/v4-to-v5/introduction-and-faq', }, label: 'Upgrade to Strapi 5', - customProps: { - new: true, - }, items: [ { - type: "doc", - label: "Introduction and FAQ", - id: "dev-docs/migration/v4-to-v5/introduction-and-faq" + type: 'doc', + label: 'Introduction and FAQ', + id: 'dev-docs/migration/v4-to-v5/introduction-and-faq', }, { - type: "doc", - label: "Step-by-step guide", - id: "dev-docs/migration/v4-to-v5/step-by-step" + type: 'doc', + label: 'Step-by-step guide', + id: 'dev-docs/migration/v4-to-v5/step-by-step', }, { - type: "doc", - label: "Upgrade tool reference", + type: 'doc', + label: 'Upgrade tool reference', id: 'dev-docs/upgrade-tool', }, { - type: "category", + type: 'category', collapsible: true, collapsed: true, - label: "Breaking changes", + label: 'Breaking changes', link: { type: 'doc', - id: 'dev-docs/migration/v4-to-v5/breaking-changes' + id: 'dev-docs/migration/v4-to-v5/breaking-changes', }, items: [ { - type: "autogenerated", - dirName: 'dev-docs/migration/v4-to-v5/breaking-changes' + type: 'autogenerated', + dirName: 'dev-docs/migration/v4-to-v5/breaking-changes', }, - ] + ], }, { type: 'category', label: 'Specific resources', collapsed: false, - link: { type: 'doc', id: 'dev-docs/migration/v4-to-v5/additional-resources/introduction' }, + link: { + type: 'doc', + id: 'dev-docs/migration/v4-to-v5/additional-resources/introduction', + }, items: [ 'dev-docs/migration/v4-to-v5/additional-resources/introduction', 'dev-docs/migration/v4-to-v5/additional-resources/from-entity-service-to-document-service', 'dev-docs/migration/v4-to-v5/additional-resources/plugins-migration', 'dev-docs/migration/v4-to-v5/additional-resources/helper-plugin', - ] - } - ] + ], + }, + ], }, - - ] + ], }; module.exports = sidebars; diff --git a/docusaurus/src/scss/_mixins.scss b/docusaurus/src/scss/_mixins.scss index 3e6d164b96..66d847a889 100644 --- a/docusaurus/src/scss/_mixins.scss +++ b/docusaurus/src/scss/_mixins.scss @@ -14,6 +14,12 @@ } } +@mixin medium-to-intermediate { + @media (min-width: 997px) and (max-width: 1298px) { + @content; + } +} + /** Mixin: Responsive */ @mixin large-up { @media (min-width: 1536px) { diff --git a/docusaurus/src/scss/badge.scss b/docusaurus/src/scss/badge.scss index f8f1533483..ed36863396 100644 --- a/docusaurus/src/scss/badge.scss +++ b/docusaurus/src/scss/badge.scss @@ -108,6 +108,20 @@ h2 .badge { --custom-badge-inside-titles-top: -.3em; } +.menu { + .badge { + &--new, + &--updated { + font-size: .65rem; + } + + &--updated { + padding-left: 6px; + padding-right: 6px; + } + } +} + /** Dark mode */ @include dark { .badge { diff --git a/docusaurus/src/scss/custom-search-bar.scss b/docusaurus/src/scss/custom-search-bar.scss index 4ee692e2b3..c21710ca45 100644 --- a/docusaurus/src/scss/custom-search-bar.scss +++ b/docusaurus/src/scss/custom-search-bar.scss @@ -43,6 +43,7 @@ } .kapa-widget-button { + width: 100%; appearance: none; background: none; border: none; @@ -100,6 +101,42 @@ } } +@include medium-to-intermediate { + .my-custom-search-bar { + max-width: 200px; + margin-top: 10px; + margin-bottom: 10px; + + .DocSearch-Button, + .kapa-widget-button { + * { + font-size: 12px !important; + } + } + + .kapa-widget-button { + position: relative; + top: -1px; + svg { + width: 12px; + margin-left: 4px; + // height: 10px; + } + } + .DocSearch-Button { + svg { + margin-right: -4px; + width: 12px; + height: 12px; + } + &-Keys { + position: relative; + top: 0; + } + } + } +} + @include dark { .my-custom-search-bar { background: var(--strapi-neutral-0); diff --git a/docusaurus/src/scss/navbar.scss b/docusaurus/src/scss/navbar.scss index b577ea7c9a..75146b9d30 100644 --- a/docusaurus/src/scss/navbar.scss +++ b/docusaurus/src/scss/navbar.scss @@ -34,12 +34,12 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]'; &__items { max-width: var(--custom-navbar-items-width); gap: var(--strapi-spacing-2); + height: 100%; } &__brand, &__logo { height: auto; - line-height: 0; } &__brand { @@ -243,6 +243,28 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]'; } } +@include medium-to-intermediate { + .navbar__logo img { + width: 150px; + height: 23px; + } + .navbar__items { + padding-right: 20px; + + &--right { + padding-right: 0; + } + } + .navbar__item { + font-size: 13px; + line-height: 14px; + } + [class*="oggleIcon"] { // purposedly omitting the "t" because selectors vary in production and local envs + width: 20px; + height: 20px; + } +} + @include dark { .kapa-widget-button { button { diff --git a/docusaurus/src/scss/sidebar.scss b/docusaurus/src/scss/sidebar.scss index 25b112fa5f..9cafa71862 100644 --- a/docusaurus/src/scss/sidebar.scss +++ b/docusaurus/src/scss/sidebar.scss @@ -162,6 +162,10 @@ $selector-color-mode-toggle-wrapper: 'div[class*="ColorModeToggle"]'; > .menu__list-item-collapsible { font-weight: 700; font-size: var(--strapi-font-size-sm); + + > .menu__link--sublist { + font-size: 16px; + } } } } diff --git a/docusaurus/static/img/assets/admin-panel-customization/red-login-button.png b/docusaurus/static/img/assets/admin-panel-customization/red-login-button.png new file mode 100644 index 0000000000..a1accc812f Binary files /dev/null and b/docusaurus/static/img/assets/admin-panel-customization/red-login-button.png differ diff --git a/docusaurus/static/img/assets/cloud/account-billing2.png b/docusaurus/static/img/assets/cloud/account-billing2.png index 97bc5f55cb..81064ed93b 100644 Binary files a/docusaurus/static/img/assets/cloud/account-billing2.png and b/docusaurus/static/img/assets/cloud/account-billing2.png differ diff --git a/docusaurus/static/img/assets/cloud/account-billing2_DARK.png b/docusaurus/static/img/assets/cloud/account-billing2_DARK.png index e637e41649..58aa94b4ac 100644 Binary files a/docusaurus/static/img/assets/cloud/account-billing2_DARK.png and b/docusaurus/static/img/assets/cloud/account-billing2_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/deploy-logs.png b/docusaurus/static/img/assets/cloud/deploy-logs.png deleted file mode 100644 index 712b057340..0000000000 Binary files a/docusaurus/static/img/assets/cloud/deploy-logs.png and /dev/null differ diff --git a/docusaurus/static/img/assets/cloud/deploy-logs_DARK.png b/docusaurus/static/img/assets/cloud/deploy-logs_DARK.png deleted file mode 100644 index ee07fb849e..0000000000 Binary files a/docusaurus/static/img/assets/cloud/deploy-logs_DARK.png and /dev/null differ diff --git a/docusaurus/static/img/assets/cloud/deploy_logs.png b/docusaurus/static/img/assets/cloud/deploy_logs.png index 1df4bdebf0..56a14e3d85 100644 Binary files a/docusaurus/static/img/assets/cloud/deploy_logs.png and b/docusaurus/static/img/assets/cloud/deploy_logs.png differ diff --git a/docusaurus/static/img/assets/cloud/deploy_logs_DARK.png b/docusaurus/static/img/assets/cloud/deploy_logs_DARK.png index 7b2b8892d0..0ea768053b 100644 Binary files a/docusaurus/static/img/assets/cloud/deploy_logs_DARK.png and b/docusaurus/static/img/assets/cloud/deploy_logs_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/environments.png b/docusaurus/static/img/assets/cloud/environments.png index f6ad58c661..1380b26398 100644 Binary files a/docusaurus/static/img/assets/cloud/environments.png and b/docusaurus/static/img/assets/cloud/environments.png differ diff --git a/docusaurus/static/img/assets/cloud/environments_DARK.png b/docusaurus/static/img/assets/cloud/environments_DARK.png index b9298c1d18..3ec9fe600b 100644 Binary files a/docusaurus/static/img/assets/cloud/environments_DARK.png and b/docusaurus/static/img/assets/cloud/environments_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/project-creation-1.png b/docusaurus/static/img/assets/cloud/project-creation-1.png index deafa9ec65..f6fa0b48aa 100644 Binary files a/docusaurus/static/img/assets/cloud/project-creation-1.png and b/docusaurus/static/img/assets/cloud/project-creation-1.png differ diff --git a/docusaurus/static/img/assets/cloud/project-creation-1_DARK.png b/docusaurus/static/img/assets/cloud/project-creation-1_DARK.png index fe1b2d4648..a339cf7e9d 100644 Binary files a/docusaurus/static/img/assets/cloud/project-creation-1_DARK.png and b/docusaurus/static/img/assets/cloud/project-creation-1_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/project-creation-2.png b/docusaurus/static/img/assets/cloud/project-creation-2.png index 03ef262b0c..3651abe263 100644 Binary files a/docusaurus/static/img/assets/cloud/project-creation-2.png and b/docusaurus/static/img/assets/cloud/project-creation-2.png differ diff --git a/docusaurus/static/img/assets/cloud/project-creation-2_DARK.png b/docusaurus/static/img/assets/cloud/project-creation-2_DARK.png index eae2ae6db0..3d6f239f83 100644 Binary files a/docusaurus/static/img/assets/cloud/project-creation-2_DARK.png and b/docusaurus/static/img/assets/cloud/project-creation-2_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/settings-general.png b/docusaurus/static/img/assets/cloud/settings-general.png index 9e10563822..0cd72d5d7a 100644 Binary files a/docusaurus/static/img/assets/cloud/settings-general.png and b/docusaurus/static/img/assets/cloud/settings-general.png differ diff --git a/docusaurus/static/img/assets/cloud/settings-general_DARK.png b/docusaurus/static/img/assets/cloud/settings-general_DARK.png index 65b582df93..db03454989 100644 Binary files a/docusaurus/static/img/assets/cloud/settings-general_DARK.png and b/docusaurus/static/img/assets/cloud/settings-general_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/settings.png b/docusaurus/static/img/assets/cloud/settings.png index 4cb6813718..de0274fa8d 100644 Binary files a/docusaurus/static/img/assets/cloud/settings.png and b/docusaurus/static/img/assets/cloud/settings.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_DARK.png b/docusaurus/static/img/assets/cloud/settings_DARK.png index cf052430f7..597632e38e 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_DARK.png and b/docusaurus/static/img/assets/cloud/settings_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_backups.png b/docusaurus/static/img/assets/cloud/settings_backups.png index 48220c1f98..3a1140373e 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_backups.png and b/docusaurus/static/img/assets/cloud/settings_backups.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_backups_DARK.png b/docusaurus/static/img/assets/cloud/settings_backups_DARK.png index 58db972e65..4ba4ab3561 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_backups_DARK.png and b/docusaurus/static/img/assets/cloud/settings_backups_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_billing.png b/docusaurus/static/img/assets/cloud/settings_billing.png index a7e34def40..0aa22b0db9 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_billing.png and b/docusaurus/static/img/assets/cloud/settings_billing.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_billing_DARK.png b/docusaurus/static/img/assets/cloud/settings_billing_DARK.png index 9237324c80..b18a0a9685 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_billing_DARK.png and b/docusaurus/static/img/assets/cloud/settings_billing_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_domains.png b/docusaurus/static/img/assets/cloud/settings_domains.png index bc98b790cb..ff083799da 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_domains.png and b/docusaurus/static/img/assets/cloud/settings_domains.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_domains_DARK.png b/docusaurus/static/img/assets/cloud/settings_domains_DARK.png index 92cb75ed86..ea32632953 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_domains_DARK.png and b/docusaurus/static/img/assets/cloud/settings_domains_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_env.png b/docusaurus/static/img/assets/cloud/settings_env.png index a897f88d76..f8e0bd7f91 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_env.png and b/docusaurus/static/img/assets/cloud/settings_env.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_env_DARK.png b/docusaurus/static/img/assets/cloud/settings_env_DARK.png index 26142c2188..be90e3dbcf 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_env_DARK.png and b/docusaurus/static/img/assets/cloud/settings_env_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_invoices.png b/docusaurus/static/img/assets/cloud/settings_invoices.png index 592ce4b726..7f6021bd13 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_invoices.png and b/docusaurus/static/img/assets/cloud/settings_invoices.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_invoices_DARK.png b/docusaurus/static/img/assets/cloud/settings_invoices_DARK.png index c262ae35d9..53b6ce910c 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_invoices_DARK.png and b/docusaurus/static/img/assets/cloud/settings_invoices_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_plans.png b/docusaurus/static/img/assets/cloud/settings_plans.png index a9b2b4c799..3760cc222b 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_plans.png and b/docusaurus/static/img/assets/cloud/settings_plans.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_plans_DARK.png b/docusaurus/static/img/assets/cloud/settings_plans_DARK.png index a51c4d7d1a..29e3109f68 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_plans_DARK.png and b/docusaurus/static/img/assets/cloud/settings_plans_DARK.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_variables.png b/docusaurus/static/img/assets/cloud/settings_variables.png index c226390e61..737e41cd0f 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_variables.png and b/docusaurus/static/img/assets/cloud/settings_variables.png differ diff --git a/docusaurus/static/img/assets/cloud/settings_variables_DARK.png b/docusaurus/static/img/assets/cloud/settings_variables_DARK.png index e1666c6c9e..903497ad83 100644 Binary files a/docusaurus/static/img/assets/cloud/settings_variables_DARK.png and b/docusaurus/static/img/assets/cloud/settings_variables_DARK.png differ diff --git a/docusaurus/static/img/assets/releases/release-details.png b/docusaurus/static/img/assets/releases/release-details.png index 5e7e66234c..ecb5a9029f 100644 Binary files a/docusaurus/static/img/assets/releases/release-details.png and b/docusaurus/static/img/assets/releases/release-details.png differ diff --git a/docusaurus/static/img/assets/releases/release-details_DARK.png b/docusaurus/static/img/assets/releases/release-details_DARK.png index 4c3b6a125e..36af073160 100644 Binary files a/docusaurus/static/img/assets/releases/release-details_DARK.png and b/docusaurus/static/img/assets/releases/release-details_DARK.png differ diff --git a/docusaurus/static/img/assets/review-workflows/review-workflows.png b/docusaurus/static/img/assets/review-workflows/review-workflows.png index 00e0ee93c5..0ed84a5071 100644 Binary files a/docusaurus/static/img/assets/review-workflows/review-workflows.png and b/docusaurus/static/img/assets/review-workflows/review-workflows.png differ diff --git a/docusaurus/static/img/assets/review-workflows/review-workflows_DARK.png b/docusaurus/static/img/assets/review-workflows/review-workflows_DARK.png index ced46f8c6a..8f58b364ef 100644 Binary files a/docusaurus/static/img/assets/review-workflows/review-workflows_DARK.png and b/docusaurus/static/img/assets/review-workflows/review-workflows_DARK.png differ diff --git a/docusaurus/static/js/ext-signals.js b/docusaurus/static/js/ext-signals.js new file mode 100644 index 0000000000..7e8ff208c3 --- /dev/null +++ b/docusaurus/static/js/ext-signals.js @@ -0,0 +1,18 @@ +(function() { + if (typeof window === 'undefined') return; + if (typeof window.signals !== 'undefined') return; + var script = document.createElement('script'); + script.src = 'https://cdn.cr-relay.com/v1/site/d071dd4e-fd79-4841-88a9-d0fd342b1e39/signals.js'; + script.async = true; + window.signals = Object.assign( + [], + ['page', 'identify', 'form'].reduce(function (acc, method){ + acc[method] = function () { + signals.push([method, arguments]); + return signals; + }; + return acc; + }, {}) + ); + document.head.appendChild(script); +})(); diff --git a/docusaurus/vercel.json b/docusaurus/vercel.json index e28253febc..6e9b5ac6ef 100644 --- a/docusaurus/vercel.json +++ b/docusaurus/vercel.json @@ -192,6 +192,10 @@ "source": "/developer-docs/latest/setup-deployment-guides/configurations/optional/rbac.html", "destination": "/dev-docs/configurations/guides/rbac" }, + { + "source": "/dev-docs/rbac", + "destination": "/dev-docs/configurations/guides/rbac" + }, { "source": "/developer-docs/latest/setup-deployment-guides/configurations/optional/api.html", "destination": "/dev-docs/configurations/api" @@ -1186,8 +1190,8 @@ "destination": "https://strapi.io/integrations/svelte-cms" }, { - "source": "/dev-docs/integrations/vue", - "destination": "https://strapi.io/integrations/vuejs-cms" + "source": "/developer-docs/latest/developer-resources/content-api/integrations/vue-js.html%23create-a-vue-js-app", + "destination": "/dev-docs/integrations/vue-js" }, { "source": "/dev-docs/integrations",