Configurations

Your application configuration lives in the config folder. All the configuration files are loaded on startup and can be accessed through the configuration provider.

When you have a file ./config/server.js with the following config:

  1. module.exports = {
  2. host: '0.0.0.0',
  3. };

You can access it as

  1. strapi.config.get('server.host', 'defaultValueIfUndefined');

Nested keys are accessible with dot-notation.

NOTE

Notice that the filename is used as a prefix to access the configurations.

Required configurations

Database

This file lets you define database connections that will be used to store your application content.

NOTE

You can find supported database and versions in the local installation process.

Path — ./config/database.js.

  • defaultConnection (string): Connection by default for models which are not related to a specific connection. Default value: default.
  • connections List of all available connections.

    • default
      • connector (string): Connector used by the current connection. Will be bookshelf.
      • settings Useful for external session stores such as Redis.
        • client (string): Database client to create the connection. sqlite or postgres or mysql.
        • host (string): Database host name. Default value: localhost.
        • port (integer): Database port.
        • database (string): Database name.
        • username (string): Username used to establish the connection.
        • password (string): Password used to establish the connection.
        • timezone (string): Set the default behavior for local time. Default value: utc Timezone options Configurations - 图1 (opens new window).
        • schema (string): Set the default database schema. Used only for Postgres DB.
        • ssl (boolean/object): For ssl database connection. Object is used to pass certificate files as strings.
      • options Options used for database connection.
        • debug (boolean): Show database exchanges and errors.
        • autoMigration (boolean): To disable auto tables/columns creation for SQL database.
        • pool Options used for database connection pooling. For default value and more information, look at Knex’s pool config documentation Configurations - 图2 (opens new window).
          • min (integer): Minimum number of connections to keep in the pool.
          • max (integer): Maximum number of connections to keep in the pool.
          • acquireTimeoutMillis (integer): Maximum time in milliseconds to wait for acquiring a connection from the pool.
          • createTimeoutMillis (integer): Maximum time in milliseconds to wait for creating a connection to be added to the pool.
          • idleTimeoutMillis (integer): Number of milliseconds to wait before destroying idle connections.
          • reapIntervalMillis (integer): How often to check for idle connections in milliseconds.
          • createRetryIntervalMillis (integer): How long to idle after a failed create before trying again in milliseconds.
  • defaultConnection (string): Connection by default for models which are not related to a specific connection. Default value: default.

  • connections List of all available connections.
    • default
      • connector (string): Connector used by the current connection. Will be mongoose.
      • settings Useful for external session stores such as Redis.
        • client (string): Database client to create the connection. Will be mongo.
        • host (string): Database host name. Default value: localhost.
        • port (integer): Database port. Default value: 27017.
        • database (string): Database name.
        • username (string): Username used to establish the connection.
        • password (string): Password used to establish the connection.
        • uri (string): This can overide all previous configurations - optional
      • options Options used for database connection.
        • ssl (boolean): For ssl database connection.
        • sslCA (string): Pass content (not filepath!) of server’s root CA for ssl connection.
        • debug (boolean): Show database exchanges and errors.
        • authenticationDatabase (string): Connect with authentication.
  1. module.exports = ({ env }) => ({
  2. defaultConnection: 'default',
  3. connections: {
  4. default: {
  5. connector: 'bookshelf',
  6. settings: {
  7. client: 'postgres',
  8. host: env('DATABASE_HOST', 'localhost'),
  9. port: env.int('DATABASE_PORT', 5432),
  10. database: env('DATABASE_NAME', 'strapi'),
  11. username: env('DATABASE_USERNAME', 'strapi'),
  12. password: env('DATABASE_PASSWORD', 'strapi'),
  13. schema: env('DATABASE_SCHEMA', 'public'), // Not Required
  14. ssl: {
  15. rejectUnauthorized: env.bool('DATABASE_SSL_SELF', false), // For self-signed certificates
  16. },
  17. },
  18. options: {
  19. ssl: env.bool('DATABASE_SSL', false),
  20. },
  21. },
  22. },
  23. });

Please note that if you need client side SSL CA verification you will need to use the ssl:{} object with the fs module to convert your CA certificate to a string. You can see an example below:

  1. module.exports = ({ env }) => ({
  2. defaultConnection: 'default',
  3. connections: {
  4. default: {
  5. connector: 'bookshelf',
  6. settings: {
  7. client: 'postgres',
  8. ...
  9. ssl: {
  10. ca: fs.readFileSync(`${__dirname}/path/to/your/ca-certificate.crt`).toString(),
  11. },
  12. },
  13. options: {
  14. ssl: true
  15. },
  16. },
  17. },
  18. });
  1. module.exports = ({ env }) => ({
  2. defaultConnection: 'default',
  3. connections: {
  4. default: {
  5. connector: 'bookshelf',
  6. settings: {
  7. client: 'mysql',
  8. host: env('DATABASE_HOST', 'localhost'),
  9. port: env.int('DATABASE_PORT', 3306),
  10. database: env('DATABASE_NAME', 'strapi'),
  11. username: env('DATABASE_USERNAME', 'strapi'),
  12. password: env('DATABASE_PASSWORD', 'strapi'),
  13. },
  14. options: {},
  15. },
  16. },
  17. });
  1. module.exports = ({ env }) => ({
  2. defaultConnection: 'default',
  3. connections: {
  4. default: {
  5. connector: 'bookshelf',
  6. settings: {
  7. client: 'sqlite',
  8. filename: env('DATABASE_FILENAME', '.tmp/data.db'),
  9. },
  10. options: {
  11. useNullAsDefault: true,
  12. },
  13. },
  14. },
  15. });
  1. module.exports = ({ env }) => ({
  2. defaultConnection: 'default',
  3. connections: {
  4. default: {
  5. connector: 'mongoose',
  6. settings: {
  7. client: 'mongo',
  8. host: env('DATABASE_HOST', 'localhost'),
  9. port: env.int('DATABASE_PORT', 27017),
  10. database: env('DATABASE_NAME', 'strapi'),
  11. username: env('DATABASE_USERNAME', 'strapi'),
  12. password: env('DATABASE_PASSWORD', 'strapi'),
  13. },
  14. options: {
  15. authenticationDatabase: env('AUTHENTICATION_DATABASE'),
  16. ssl: env('DATABASE_SSL'),
  17. },
  18. },
  19. },
  20. });

TIP

Take a look at the database’s guide for more details.

Configuration in database

Configuration files are not multi server friendly. So we created a data store for config you will want to update in production.

Get settings
  • environment (string): Sets the environment you want to store the data in. By default it’s current environment (can be an empty string if your config is environment agnostic).
  • type (string): Sets if your config is for an api, plugin or core. By default it’s core.
  • name (string): You have to set the plugin or api name if type is api or plugin.
  • key (string, required): The name of the key you want to store.
  1. // strapi.store(object).get(object);
  2. // create reusable plugin store variable
  3. const pluginStore = strapi.store({
  4. environment: strapi.config.environment,
  5. type: 'plugin',
  6. name: 'users-permissions',
  7. });
  8. await pluginStore.get({ key: 'grant' });
Set settings
  • value (any, required): The value you want to store.
  1. // strapi.store(object).set(object);
  2. // create reusable plugin store variable
  3. const pluginStore = strapi.store({
  4. environment: strapi.config.environment,
  5. type: 'plugin',
  6. name: 'users-permissions'
  7. });
  8. await pluginStore.set({
  9. key: 'grant',
  10. value: {
  11. ...
  12. }
  13. });

Databases installation guides

Strapi gives you the option to choose the most appropriate database for your project. It currently supports PostgreSQL, MongoDB, SQLite, MySQL and MariaDB. The following documentation covers how to install these databases locally (for development purposes) and on various hosted or cloud server solutions (for staging or production purposes).

TIP

Deploying Strapi itself is covered in the Deployment Guide.

[Configurations - 图3

SQLite

Installation guide for SQLite database

](https://strapi.io/documentation/developer-docs/latest/setup-deployment-guides/configurations/databases/sqlite.html)

[Configurations - 图4

MongoDB

Installation guide for MongoDB database

](https://strapi.io/documentation/developer-docs/latest/setup-deployment-guides/configurations/databases/mongodb.html)

Server

Minimal Server Config

This is the default config created with any new project, all these keys are required at the very least, environmental configs do not need to contain all these values so long as they exist in the default ./config/server.js.

Path — ./config/server.js.

  1. module.exports = ({ env }) => ({
  2. host: env('HOST', '0.0.0.0'),
  3. port: env.int('PORT', 1337),
  4. admin: {
  5. auth: {
  6. secret: env('ADMIN_JWT_SECRET', 'someSecretKey'),
  7. },
  8. },
  9. });

Full Server Config

This is an example of a full configuration, typically certain keys do not need to present in environmental configs, and not all of these keys are required. Please see the table below to see what each key does.

Path — ./config/server.js.

  1. module.exports = ({ env }) => ({
  2. host: env('HOST', '0.0.0.0'),
  3. port: env.int('PORT', 1337),
  4. socket: '/tmp/nginx.socket', // only use if absolutely required
  5. emitErrors: false,
  6. url: env('PUBLIC_URL', 'https://api.example.com'),
  7. proxy: env.bool('IS_PROXIED', true),
  8. cron: {
  9. enabled: env.bool('CRON_ENABLED', false),
  10. },
  11. admin: {
  12. auth: {
  13. events: {
  14. onConnectionSuccess(e) {
  15. console.log(e.user, e.provider);
  16. },
  17. onConnectionError(e) {
  18. console.error(e.error, e.provider);
  19. },
  20. },
  21. secret: env('ADMIN_JWT_SECRET', 'someSecretKey'),
  22. },
  23. url: env('PUBLIC_ADMIN_URL', '/dashboard'),
  24. autoOpen: false,
  25. watchIgnoreFiles: [
  26. './my-custom-folder', // Folder
  27. './scripts/someScript.sh', // File
  28. ],
  29. host: 'localhost', // Only used for --watch-admin
  30. port: 8003, // Only used for --watch-admin
  31. serveAdminPanel: env.bool('SERVE_ADMIN', true),
  32. forgotPassword: {
  33. from: 'no-reply@example.com',
  34. replyTo: 'no-reply@example.com',
  35. },
  36. },
  37. });
Available options
PropertyDescriptionTypeDefault
hostHost namestringlocalhost
portPort on which the server should be running.integer1337
socketListens on a socket. Host and port are cosmetic when this option is provided and likewise use url to generate proper urls when using this option. This option is useful for running a server without exposing a port and using proxy servers on the same machine (e.g Heroku nginx buildpackConfigurations - 图5 (opens new window))string | integer/tmp/nginx.socket
emitErrorsEnable errors to be emitted to koa when they happen in order to attach custom logic or use error reporting services.booleanfalse
urlPublic url of the server. Required for many different features (ex: reset password, third login providers etc.). Also enables proxy support such as Apache or Nginx, example: https://mywebsite.com/api. The url can be relative, if so, it is used with http://${host}:${port} as the base url. An absolute url is however recommended.string‘’
proxySet the koa variable app.proxy. When true, proxy header fields will be trusted.booleanfalse
cronCron configuration (powered by node-scheduleConfigurations - 图6 (opens new window))Object
cron.enabledEnable or disable CRON tasks to schedule jobs at specific dates.booleanfalse
adminAdmin panel configurationObject
admin.authAuthentication configurationObject
admin.auth.secretSecret used to encode JWT tokensstringundefined
admin.auth.eventsRecord of all the events subscribers registered for the authenticationobject{}
admin.auth.events.onConnectionSuccessFunction called when an admin user log in successfully to the administration panelfunctionundefined
admin.auth.events.onConnectionErrorFunction called when an admin user fails to log in to the administration panelfunctionundefined
admin.urlUrl of your admin panel. Default value: /admin. Note: If the url is relative, it will be concatenated with url.string/admin
admin.autoOpenEnable or disabled administration opening on start.booleantrue
admin.watchIgnoreFilesAdd custom files that should not be watched during development. See more hereConfigurations - 图7 (opens new window) (property ignored).Array(string)[]
admin.hostUse a different host for the admin panel. Only used along with strapi develop —watch-adminstringlocalhost
admin.portUse a different port for the admin panel. Only used along with strapi develop —watch-adminstring8000
admin.serveAdminPanelIf false, the admin panel won’t be served. Note: the index.html will still be served, see defaultIndex optionbooleantrue
admin.forgotPasswordSettings to customize the forgot password email (see more here: Forgot Password Email)Object{}
admin.forgotPassword.emailTemplateEmail template as defined in email pluginObjectDefault templateConfigurations - 图8 (opens new window)
admin.forgotPassword.fromSender mail addressstringDefault value defined in your provider configuration
admin.forgotPassword.replyToDefault address or addresses the receiver is asked to reply tostringDefault value defined in your provider configuration

Formats

You can either use .js or .json files to configure your application.

When using a .js you can either export an object:

  1. module.exports = {
  2. mySecret: 'someValue',
  3. };

or a function returning a configuration object (recommended usage). The function will get access to the env utility.

  1. module.exports = ({ env }) => {
  2. return {
  3. mySecret: 'someValue',
  4. };
  5. };

Optional configurations

Environment

In case you need specific static configurations for specific environments, and using environment variables becomes tedious, Strapi configurations can be created per environment in ./config/env/{env}/{filename}.

These configurations will be merged into the base configurations defined in the ./config folder. The environment is based on the NODE_ENV environment variable (defaults to development).

When starting Strapi with NODE_ENV=production it will load the configuration from ./config/* and ./config/env/production/*. Everything defined in the production config will override the default config.

In combination with environment variables this pattern becomes really powerful.

Examples:

./config/server.js

  1. module.exports = {
  2. host: '127.0.0.1',
  3. };

./config/env/production/server.js

  1. module.exports = ({ env }) => ({
  2. host: env('HOST', '0.0.0.0'),
  3. });

When starting your application:

  1. yarn start
  2. # uses host 127.0.0.1
  1. NODE_ENV=production yarn start
  2. # uses host 0.0.0.0
  1. HOST=10.0.0.1 NODE_ENV=production yarn start
  2. # uses host 10.0.0.1

Environment variables

List of Strapi’s environment variables

Some settings can only be modified through environment variables. Here is a list of those settings are associated environment variable names:

namedescriptiontypedefault
STRAPI_DISABLE_UPDATE_NOTIFICATIONDon’t show the notification message about updating strapi in the terminalbooleanfalse
STRAPI_HIDE_STARTUP_MESSAGEDon’t show the startup message in the terminalbooleanfalse
STRAPI_TELEMETRY_DISABLEDDon’t send telemetry usage data to Strapibooleanfalse
STRAPI_LOG_TIMESTAMPAdd the timestamp info in logsbooleanfalse
STRAPI_LOG_LEVELSelect the level of logs among fatal, error, warn, info, debug, tracestring‘info’
STRAPI_LOG_FORCE_COLORForce colors to be displayed even in environments that are not supposed to have colors enabled (ex: outside of a TTY)booleantrue
STRAPI_LOG_PRETTY_PRINTLog lines are displayed as text instead of as objectbooleantrue
STRAPI_LICENSEThe license key to activate the Enterprise Editionstringundefined
NODE_ENVType of environment where the app is runningstring‘development’
BROWSEROpen the admin panel in the browser after startupbooleantrue
ENV_PATHPath to the file that contains your environment variablesstring‘./.env’

Configuration using environment variables

In most use cases you will have different configurations between your environments. For example: your database credentials.

Instead of writing those credentials into your configuration files, you can define those variables in a .env file at the root of your application.

Example:

Path — .env

  1. DATABASE_PASSWORD=acme

If you want to customize the path of the .env file to load you can set an environment variable called ENV_PATH before starting your application:

  1. $ ENV_PATH=/absolute/path/to/.env npm run start

Now you can access those variables in your configuration files and application. You can use process.env.{varName} to access those variables anywhere.

In your configuration files you will have access to a env utility that allows defining defaults and casting values.

Path — ./config/database.js

  1. module.exports = ({ env }) => ({
  2. connections: {
  3. default: {
  4. settings: {
  5. password: env('DATABASE_PASSWORD'),
  6. },
  7. },
  8. },
  9. });

Casting environment variables

  1. // Returns the env if defined without casting it
  2. env('VAR', 'default');
  3. // Cast to int (using parseInt)
  4. env.int('VAR', 0);
  5. // Cast to float (using parseFloat)
  6. env.float('VAR', 3.14);
  7. // Cast to boolean (check if the value is equal to 'true')
  8. env.bool('VAR', true);
  9. // Cast to js object (using JSON.parse)
  10. env.json('VAR', { key: 'value' });
  11. // Cast to an array (syntax: ENV_VAR=[value1, value2, value3] | ENV_VAR=["value1", "value2", "value3"])
  12. env.array('VAR', [1, 2, 3]);
  13. // Case to date (using new Date(value))
  14. env.date('VAR', new Date());

API

Path — ./config/api.js.

  1. module.exports = ({ env }) => ({
  2. responses: {
  3. privateAttributes: ['_v', 'id', 'created_at'],
  4. },
  5. rest: {
  6. defaultLimit: 100,
  7. maxLimit: 250,
  8. },
  9. });

Available options

PropertyDescriptionTypeDefault
responsesGlobal API response configurationObject
responses.privateAttributesSet of globally defined attributes to be treated as private. E.g. _v when using MongoDb or timestamps like created_at, updated_at can be treated as privateString array[]
restREST API configurationObject
rest.defaultLimitSpecifies default _limit parameter used in API callsInteger100
rest.maxLimitSpecifies max allowed number that can be requested as _limit. Default to null which fetches all resultsIntegernull

Plugins

A plugin is like a small independent sub-application. It has its own business logic with dedicated models, controllers, services, middlewares or hooks. It can also have its own UI integrated in the admin panel.

TIP

Please refer to the plugins documentation for more information.

Hooks

The hooks are modules that add functionality to the core. They are loaded during the server boot.

Structure

File structure
  1. module.exports = strapi => {
  2. const hook = {
  3. /**
  4. * Default options
  5. */
  6. defaults: {
  7. // config object
  8. },
  9. /**
  10. * Initialize the hook
  11. */
  12. async initialize() {
  13. // await someAsyncCode()
  14. // const settings = {...this.defaults, ...strapi.config.hook.settings.**};
  15. },
  16. };
  17. return hook;
  18. };
  • defaults (object): Contains the default configurations.
  • initialize (function): Called during the server boot.

The configurations of the hook are accessible through strapi.config.hook.settings.**.

The hooks are accessible through the strapi.hook variable.

Node modules

Every folder that follows this name pattern strapi-hook-* in your ./node_modules folder will be loaded as a hook.

A hook needs to follow the structure below:

  1. /strapi-hook-[...]
  2. └─── lib
  3. - index.js
  4. - LICENSE.md
  5. - package.json
  6. - README.md

The index.js is the entry point to your hook. It should look like the example above.

Custom local hooks

The framework allows loading hooks from the project directly without having to install them from npm. It’s a great way to take advantage of the features of the hooks system for code that doesn’t need to be shared between apps. To achieve this, you have to create a ./hooks folder at the root of your project and put the hooks into it.

  1. /project
  2. └─── admin
  3. └─── api
  4. └─── config
  5. - hook.js
  6. └─── hooks
  7. └─── strapi-documentation
  8. - index.js
  9. └─── strapi-server-side-rendering
  10. - index.js
  11. └─── public
  12. - favicon.ico
  13. - package.json
  14. - server.js

Configuration and activation

To activate and configure hooks with custom options, you need to add/edit your ./config/hook.js file in your Strapi app. A hook specific timeout value will overwrite the global timeout value, the default timeout value is 1000 milliseconds.

  1. module.exports = {
  2. timeout: 2000,
  3. settings: {
  4. 'hook-name': {
  5. enabled: true,
  6. timeout: 3000,
  7. },
  8. },
  9. };

Middlewares

The middlewares are functions which are composed and executed in a stack-like manner upon request. If you are not familiar with the middleware stack in Koa, we highly recommend you to read the Koa’s documentation introduction Configurations - 图9 (opens new window).

Structure

File structure
  1. module.exports = strapi => {
  2. return {
  3. // can also be async
  4. initialize() {
  5. strapi.app.use(async (ctx, next) => {
  6. // await someAsyncCode()
  7. await next();
  8. // await someAsyncCode()
  9. });
  10. },
  11. };
  12. };
  • initialize (function): Called during the server boot.

The middlewares are accessible through the strapi.middleware variable.

Node modules

Every folder that follows this name pattern strapi-middleware-* in your ./node_modules folder will be loaded as a middleware.

A middleware needs to follow the structure below:

  1. /middleware
  2. └─── lib
  3. - index.js
  4. - LICENSE.md
  5. - package.json
  6. - README.md

The index.js is the entry point to your middleware. It should look like the example above.

Custom middlewares

The framework allows the application to override the default middlewares and add new ones. You have to create a ./middlewares folder at the root of your project and put the middlewares into it.

  1. /project
  2. └─── api
  3. └─── config
  4. └─── middlewares
  5. └─── responseTime // It will override the core default responseTime middleware.
  6. - index.js
  7. └─── views // It will be added into the stack of middleware.
  8. - index.js
  9. └─── public
  10. - favicon.ico
  11. - package.json
  12. - server.js

Every middleware will be injected into the Koa stack. To manage the load order, please refer to the Middleware order section.

Configuration and activation

To configure the middlewares of your application, you need to create or edit the ./config/middleware.js file in your Strapi app.

By default this file doesn’t exist, you will have to create it.

Available options

  • timeout (integer): Defines the maximum allowed milliseconds to load a middleware.
  • load (Object): Configuration middleware loading. See details here
  • settings (Object): Configuration of each middleware
    • {middlewareName} (Object): Configuration of one middleware
      • enabled (boolean): Tells Strapi to run the middleware or not
Settings

Example:

Path — ./config/middleware.js.

  1. module.exports = {
  2. //...
  3. settings: {
  4. cors: {
  5. origin: ['http://localhost', 'https://mysite.com', 'https://www.mysite.com'],
  6. },
  7. },
  8. };
Load order

The middlewares are injected into the Koa stack asynchronously. Sometimes it happens that some of these middlewares need to be loaded in a specific order. To define a load order, create or edit the file ./config/middleware.js.

Path — ./config/middleware.js.

  1. module.exports = {
  2. load: {
  3. before: ['responseTime', 'logger', 'cors', 'responses'],
  4. order: [
  5. "Define the middlewares' load order by putting their name in this array in the right order",
  6. ],
  7. after: ['parser', 'router'],
  8. },
  9. };
  • load:
    • before: Array of middlewares that need to be loaded in the first place. The order of this array matters.
    • order: Array of middlewares that need to be loaded in a specific order.
    • after: Array of middlewares that need to be loaded at the end of the stack. The order of this array matters.

Core middleware configurations

The core of Strapi embraces a small list of middlewares for performances, security and great error handling.

  • boom
  • cors
  • cron
  • csp
  • favicon
  • gzip
  • hsts
  • ip
  • language
  • logger
  • p3p
  • parser
  • public
  • responses
  • responseTime
  • router
  • session
  • xframe
  • xss

TIP

The following middlewares cannot be disabled: responses, router, logger and boom.

Global middlewares
  • favicon
    • path (string): Path to the favicon file. Default value: favicon.ico.
    • maxAge (integer): Cache-control max-age directive in ms. Default value: 86400000.
  • public
    • path (string): Path to the public folder. Default value: ./public.
    • maxAge (integer): Cache-control max-age directive in ms. Default value: 60000.
    • defaultIndex (boolean): Display default index page at / and /index.html. Default value: true.
Request middlewares
  • session
    • enabled (boolean): Enable or disable sessions. Default value: false.
  • logger
    • level (string): Default log level. Default value: debug.
    • exposeInContext (boolean): Expose logger in context so it can be used through strapi.log.info(‘my log’). Default value: true.
    • requests (boolean): Enable or disable requests logs. Default value: false.
  • parser (See koa-body Configurations - 图10 (opens new window) for more information)
    • enabled(boolean): Enable or disable parser. Default value: true.
    • multipart (boolean): Enable or disable multipart bodies parsing. Default value: true.
    • jsonLimit (string|integer): The byte (if integer) limit of the JSON body. Default value: 1mb.
    • formLimit (string|integer): The byte (if integer) limit of the form body. Default value: 56k.
    • queryStringParser (see qs Configurations - 图11 (opens new window) for a full list of options).
      • arrayLimit (integer): the maximum length of an array in the query string. Any array members with an index of greater than the limit will instead be converted to an object with the index as the key. Default value: 100.
      • depth (integer): maximum parsing depth of nested query string objects. Default value: 20.

TIP

The session doesn’t work with mongo as a client. The package that we should use is broken for now.

Response middlewares
  • gzip Configurations - 图12 (opens new window)
  • responseTime
    • enabled (boolean): Enable or not X-Response-Time header to response. Default value: false.
  • poweredBy
    • enabled (boolean): Enable or not X-Powered-By header to response. Default value: true.
    • value (string): The value of the header. Default value: Strapi <strapi.io>

TIP

gzip compression via koa-compress uses Brotli Configurations - 图14 (opens new window) by default, but is not configured with sensible defaults for most cases. If you experience slow response times with gzip enabled, consider disabling Brotli by passing {br: false} as an option. You may also pass more sensible params with {br: { params: { // YOUR PARAMS HERE } }}

Security middlewares
  • csp Configurations - 图15 (opens new window)
    • enabled (boolean): Enable or disable CSP to avoid Cross Site Scripting (XSS) and data injection attacks.
    • policy (string): Configures the Content-Security-Policy header. If not specified uses default value. Default value: undefined.
  • p3p Configurations - 图16 (opens new window)
    • enabled (boolean): Enable or disable p3p.
  • hsts Configurations - 图17 (opens new window)
    • enabled (boolean): Enable or disable HSTS.
    • maxAge (integer): Number of seconds HSTS is in effect. Default value: 31536000.
    • includeSubDomains (boolean): Applies HSTS to all subdomains of the host. Default value: true.
  • xframe Configurations - 图18 (opens new window)
    • enabled (boolean): Enable or disable X-FRAME-OPTIONS headers in response.
    • value (string): The value for the header, e.g. DENY, SAMEORIGIN or ALLOW-FROM uri. Default value: SAMEORIGIN.
  • xss Configurations - 图19 (opens new window)
    • enabled (boolean): Enable or disable XSS to prevent Cross Site Scripting (XSS) attacks in older IE browsers (IE8).
  • cors Configurations - 图20 (opens new window)
    • enabled (boolean): Enable or disable CORS to prevent your server to be requested from another domain.
    • origin (string or array): Allowed URLs (http://example1.com, http://example2.com, ['http://www.example1.com', 'http://example1.com'] or allows everyone *). Default value: *.
    • expose (array): Configures the Access-Control-Expose-Headers CORS header. If not specified, no custom headers are exposed. Default value: ["WWW-Authenticate", "Server-Authorization"].
    • maxAge (integer): Configures the Access-Control-Max-Age CORS header. Default value: 31536000.
    • credentials (boolean): Configures the Access-Control-Allow-Credentials CORS header. Default value: true.
    • methods (array)|String - Configures the Access-Control-Allow-Methods CORS header. Default value: ["GET", "POST", "PUT", "PATCH", "DELETE", "OPTIONS", "HEAD"].
    • headers (array): Configures the Access-Control-Allow-Headers CORS header. If not specified, defaults to reflecting the headers specified in the request’s Access-Control-Request-Headers header. Default value: ["Content-Type", "Authorization", "X-Frame-Options"].
  • ip
    • enabled (boolean): Enable or disable IP blocker. Default value: false.
    • whiteList (array): Whitelisted IPs. Default value: [].
    • blackList (array): Blacklisted IPs. Default value: [].

Example

Create your custom middleware.

Path — ./middlewares/timer/index.js

  1. module.exports = strapi => {
  2. return {
  3. initialize() {
  4. strapi.app.use(async (ctx, next) => {
  5. const start = Date.now();
  6. await next();
  7. const delta = Math.ceil(Date.now() - start);
  8. ctx.set('X-Response-Time', delta + 'ms');
  9. });
  10. },
  11. };
  12. };

Enable the middleware in environments settings.

Load a middleware at the very first place

Path — ./config/middleware.js

  1. module.exports = {
  2. load: {
  3. before: ['timer', 'responseTime', 'logger', 'cors', 'responses', 'gzip'],
  4. order: [
  5. "Define the middlewares' load order by putting their name in this array is the right order",
  6. ],
  7. after: ['parser', 'router'],
  8. },
  9. settings: {
  10. timer: {
  11. enabled: true,
  12. },
  13. },
  14. };

Functions

The ./config/functions/ folder contains a set of JavaScript files in order to add dynamic and logic based configurations.

All functions that are exposed in this folder are accessible via strapi.config.functions['fileName']();

Bootstrap

Path — ./config/functions/bootstrap.js.

The bootstrap function is called at every server start. You can use it to add a specific logic at this moment of your server’s lifecycle.

Here are some use cases:

  • Create an admin user if there isn’t one.
  • Fill the database with some necessary data.
  • Load some environment variables.

The bootstrap function can be synchronous or asynchronous.

Synchronous

  1. module.exports = () => {
  2. // some sync code
  3. };

Return a promise

  1. module.exports = () => {
  2. return new Promise(/* some code */);
  3. };

Asynchronous

  1. module.exports = async () => {
  2. await someSetup();
  3. };

CRON tasks

CRON tasks allow you to schedule jobs (arbitrary functions) for execution at specific dates, with optional recurrence rules. It only uses a single timer at any given time (rather than reevaluating upcoming jobs every second/minute).

This feature is powered by node-schedule Configurations - 图21 (opens new window) node modules. Check it for more information.

WARNING

Make sure the enabled cron config is set to true in ./config/server.js file.

The cron format consists of:

  1. * * * * * *
  2. |
  3. day of week (0 - 7) (0 or 7 is Sun)
  4. └───── month (1 - 12)
  5. └────────── day of month (1 - 31)
  6. └─────────────── hour (0 - 23)
  7. └──────────────────── minute (0 - 59)
  8. └───────────────────────── second (0 - 59, OPTIONAL)

To define a CRON job, add your logic like below:

Path — ./config/functions/cron.js.

  1. module.exports = {
  2. /**
  3. * Simple example.
  4. * Every monday at 1am.
  5. */
  6. '0 0 1 * * 1': () => {
  7. // Add your own logic here (e.g. send a queue of email, create a database backup, etc.).
  8. },
  9. };

If your CRON task is required to run based on a specific timezone then you can configure the task like below:

  1. module.exports = {
  2. /**
  3. * CRON task with timezone example.
  4. * Every monday at 1am for Asia/Dhaka timezone.
  5. * List of valid timezones: https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List
  6. */
  7. '0 0 1 * * 1': {
  8. task: () => {
  9. // Add your own logic here (e.g. send a queue of email, create a database backup, etc.).
  10. },
  11. options: {
  12. tz: 'Asia/Dhaka',
  13. },
  14. },
  15. };

Database ORM customization

When present, they are loaded to let you customize your database connection instance, for example for adding some plugin, customizing parameters, etc.

You will need to install the plugin using the normal npm install the-plugin-name or any of the other supported package tools such as yarn then follow the below examples to load them.

As an example, for using the mongoose-simple-random plugin for MongoDB, you can register it like this:

Path — ./config/functions/mongoose.js.

  1. 'use strict';
  2. const random = require('mongoose-simple-random');
  3. module.exports = (mongoose, connection) => {
  4. mongoose.plugin(random);
  5. };

Another example would be using the bookshelf-uuid plugin for MySQL, you can register it like this:

Path — ./config/functions/bookshelf.js.

  1. 'use strict';
  2. module.exports = (bookshelf, connection) => {
  3. bookshelf.plugin('bookshelf-uuid');
  4. };

Public assets

Public assets are static files such as images, video, css, 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.

Example:

An image named company-logo.png in ./public/ is accessible through /company-logo.png URL.

TIP

index.html files are served if the request corresponds to a folder name (/pictures url will try to serve public/pictures/index.html file).

WARNING

The dotfiles are not exposed. It means that every file name that starts with ., such as .htaccess or .gitignore, are not served.

Single Sign On Gold Configurations - 图22 (opens new window)


Single-Sign-On on Strapi allows you to configure additional sign-in and sign-up methods for your administration panel.

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 Configurations - 图23 (opens new window).

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.
  • 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.

Usage

SSO configuration lives in the server configuration of your application found within /config/server.js.

Accessing the configuration

The providers’ configuration should be written within the admin.auth.providers path of the server configuration.

admin.auth.providers is an array of provider configuration.

  1. module.exports = ({ env }) => ({
  2. // ...
  3. admin: {
  4. // ...
  5. auth: {
  6. providers: [], // The providers' configuration lives there
  7. },
  8. },
  9. });
Provider Configuration

A provider’s configuration is a Javascript object built with the following properties:

NameRequiredTypeDescription
uidtruestringThe UID of the strategy. It must match the strategy’s name
displayNametruestringThe name that will be used on the login page to reference the provider
iconfalsestringAn image URL. If specified, it will replace the displayName on the login page
createStrategytruefunctionA factory that will build and return a new passport strategy for your provider. Takes the strapi instance as parameter

TIP

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.

The createStrategy Factory

A passport strategy is usually built by instantiating it using 2 parameters: the configuration object, and the verify function.

Configuration Object

The configuration object depends on the strategy needs, but often asks for a callback URL to be redirected to once the connection has been made on the provider side.

You can generate a specific callback URL for your provider using the getStrategyCallbackURL method. This URL also needs to be written on the provider side in order to allow redirection from it.

The format of the callback URL is the following: /admin/connect/<provider_uid>.

TIP

strapi.admin.services.passport.getStrategyCallbackURL is a Strapi helper you can use to get a callback URL for a specific provider. It takes a provider name as a parameter and returns a URL.

If needed, this is also where you will put your client ID and secret key for your OAuth2 application.

Verify Function

The verify function is used here as a middleware allowing the user to transform and make extra processing on the data returned from the provider API.

This function always takes a done method as last parameter which is used to transfer needed data to the Strapi layer of SSO.

Its signature is the following: void done(error: any, data: object); and it follows the following rules:

  • If error is not set to null, then the data sent is ignored, and the controller will throw an error.
  • If the SSO’s auto-registration feature is disabled, then the data object only need to be composed of an email property.
  • If the SSO’s auto-registration feature is enabled, then you will need to define (in addition to the email) either a username property or both firstname and lastname within the data oject.
Adding a provider

Adding a new provider means adding a new way for your administrators to log-in.

To achieve a great flexibility and a large choice of provider, Strapi uses Passport.js Configurations - 图24 (opens new window). Any valid passport strategy that doesn’t need additional custom data should therefore work with Strapi.

WARNING

Strategies such as ldapauth Configurations - 图25 (opens new window) 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 Configurations - 图26 (opens new window). You can also use services such as Okta and Auth0 as bridge services.

Configuring the provider

To configure a provider, follow the procedure below:

  1. Make sure to import your strategy in your server configuration file, either from an installed package or a local file.
  2. You’ll need to add a new item to the admin.auth.providers array in your server configuration that will match the format given above
  3. Restart your application, the provider should appear on your admin login page.
Examples

Using: passport-google-oauth2 Configurations - 图27 (opens new window)

  1. yarn add passport-google-oauth2
  1. npm install --save passport-google-oauth2

/config/server.js

  1. 'use strict';
  2. const GoogleStrategy = require('passport-google-oauth2');
  3. module.exports = ({ env }) => ({
  4. // ...
  5. admin: {
  6. // ...
  7. auth: {
  8. /// ...
  9. providers: [
  10. {
  11. uid: 'google',
  12. displayName: 'Google',
  13. icon: 'https://cdn2.iconfinder.com/data/icons/social-icons-33/128/Google-512.png',
  14. createStrategy: strapi =>
  15. new GoogleStrategy(
  16. {
  17. clientID: env('GOOGLE_CLIENT_ID'),
  18. clientSecret: env('GOOGLE_CLIENT_SECRET'),
  19. scope: [
  20. 'https://www.googleapis.com/auth/userinfo.email',
  21. 'https://www.googleapis.com/auth/userinfo.profile',
  22. ],
  23. callbackURL: strapi.admin.services.passport.getStrategyCallbackURL('google'),
  24. },
  25. (request, accessToken, refreshToken, profile, done) => {
  26. done(null, {
  27. email: profile.email,
  28. firstname: profile.given_name,
  29. lastname: profile.family_name,
  30. });
  31. }
  32. ),
  33. },
  34. ],
  35. },
  36. },
  37. });

Using: passport-github Configurations - 图28 (opens new window)

  1. yarn add passport-github2
  1. npm install --save passport-github2

/config/server.js

  1. 'use strict';
  2. const GithubStrategy = require('passport-github2');
  3. module.exports = ({ env }) => ({
  4. // ...
  5. admin: {
  6. // ...
  7. auth: {
  8. // ...
  9. providers: [
  10. {
  11. uid: 'github',
  12. displayName: 'Github',
  13. icon: 'https://cdn1.iconfinder.com/data/icons/logotypes/32/github-512.png',
  14. createStrategy: strapi =>
  15. new GithubStrategy(
  16. {
  17. clientID: env('GITHUB_CLIENT_ID'),
  18. clientSecret: env('GITHUB_CLIENT_SECRET'),
  19. scope: ['user:email'],
  20. callbackURL: strapi.admin.services.passport.getStrategyCallbackURL('github'),
  21. },
  22. (accessToken, refreshToken, profile, done) => {
  23. done(null, {
  24. email: profile.emails[0].value,
  25. username: profile.username,
  26. });
  27. }
  28. ),
  29. },
  30. ],
  31. },
  32. },
  33. });

Using: passport-discord Configurations - 图29 (opens new window)

  1. yarn add passport-discord
  1. npm install --save passport-discord

/config/server.js

  1. 'use strict';
  2. const DiscordStrategy = require('passport-discord');
  3. module.exports = ({ env }) => ({
  4. // ...
  5. admin: {
  6. // ...
  7. auth: {
  8. // ...
  9. providers: [
  10. {
  11. uid: 'discord',
  12. displayName: 'Discord',
  13. icon: 'https://cdn0.iconfinder.com/data/icons/free-social-media-set/24/discord-512.png',
  14. createStrategy: strapi =>
  15. new DiscordStrategy(
  16. {
  17. clientID: env('DISCORD_CLIENT_ID'),
  18. clientSecret: env('DISCORD_SECRET'),
  19. callbackURL: strapi.admin.services.passport.getStrategyCallbackURL('discord'),
  20. scope: ['identify', 'email'],
  21. },
  22. (accessToken, refreshToken, profile, done) => {
  23. done(null, {
  24. email: profile.email,
  25. username: `${profile.username}#${profile.discriminator}`,
  26. });
  27. }
  28. ),
  29. },
  30. ],
  31. },
  32. },
  33. });

Using: passport-azure-ad-oauth2 Configurations - 图30 (opens new window)

  1. yarn add passport-azure-ad-oauth2 jsonwebtoken
  1. npm install --save passport-azure-ad-oauth2 jsonwebtoken

/config/server.js

  1. 'use strict';
  2. const AzureAdOAuth2Strategy = require('passport-azure-ad-oauth2');
  3. const jwt = require('jsonwebtoken');
  4. module.exports = ({ env }) => ({
  5. // ...
  6. admin: {
  7. // ...
  8. auth: {
  9. // ...
  10. providers: [
  11. {
  12. uid: 'azure_ad_oauth2',
  13. displayName: 'Microsoft',
  14. icon:
  15. 'https://upload.wikimedia.org/wikipedia/commons/thumb/9/96/Microsoft_logo_%282012%29.svg/320px-Microsoft_logo_%282012%29.svg.png',
  16. createStrategy: strapi =>
  17. new AzureAdOAuth2Strategy(
  18. {
  19. clientID: env('MICROSOFT_CLIENT_ID', ''),
  20. clientSecret: env('MICROSOFT_CLIENT_SECRET', ''),
  21. scope: ['user:email'],
  22. tenant: env('MICROSOFT_TENANT_ID', ''),
  23. callbackURL: strapi.admin.services.passport.getStrategyCallbackURL(
  24. 'azure_ad_oauth2'
  25. ),
  26. },
  27. (accessToken, refreshToken, params, profile, done) => {
  28. var waadProfile = jwt.decode(params.id_token, '', true);
  29. done(null, {
  30. email: waadProfile.upn,
  31. username: waadProfile.upn,
  32. });
  33. }
  34. ),
  35. },
  36. ],
  37. },
  38. },
  39. });
Advanced Customization
Admin Panel URL

If your administration panel lives on a different host/port than your Strapi server, you will need to modify the admin URL. To do so, head to your /config/server.js configuration file and tweak the admin.url field.

For example, if your admin application has been started on https://api.example.com, your configuration will look like the following:

/config/server.js

  1. module.exports = () => ({
  2. // ...
  3. admin: {
  4. // ...
  5. url: 'https://api.example.com/admin',
  6. },
  7. });
Custom Logic

In some scenarios, you will want to write additional logic for your connection workflow such as:

  • Restricting connection and registration for a specific domain
  • Triggering actions on connection attempt
  • Analytics

The easiest way to do so is to plug into the verify function of your strategy and write some code.

For example, if you want to allow only people with an official strapi.io email address, you can instantiate your strategy like this:

  1. const strategyInstance = new Strategy(configuration, ({ email, username }, done) => {
  2. // If the email ends with @strapi.io
  3. if (email.endsWith('@strapi.io')) {
  4. // Then we continue with the data given by the provider
  5. return done(null, { email, username });
  6. }
  7. // Otherwise, we continue by sending an error to the done function
  8. done(new Error('Forbidden email address'));
  9. });
Authentication Events

The SSO feature adds a new authentication event: onSSOAutoRegistration.

This event is triggered whenever a user is created using the auto-register feature added by SSO. It contains the created user (event.user), and the provider used to make the registration (event.provider).

Example:

/config/server.js

  1. module.exports = () => ({
  2. // ...
  3. admin: {
  4. // ...
  5. auth: {
  6. // ...
  7. events: {
  8. onConnectionSuccess(e) {},
  9. onConnectionError(e) {},
  10. // ...
  11. onSSOAutoRegistration(e) {
  12. const { user, provider } = e;
  13. console.log(
  14. `A new user (${user.id}) has been automatically registered using ${provider}`
  15. );
  16. },
  17. },
  18. },
  19. },
  20. });

Role-Based Access Control Bronze Silver Gold Configurations - 图31 (opens new window)

🚧 This API is considered unstable for now.

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. The Community Edition of Strapi offers 3 default roles (Author, Editor, and Super Admin). To go further, creating custom conditions for any type of permission is also possible. This requires an Enterprise Edition with at minimum a Bronze licence plan.

Declaring new conditions

Declare a single condition as an object, and multiple conditions as an array of objects. Each condition object can have 5 possible properties:

  • displayName (string): the condition name as shown in the admin panel,
  • name (string): the condition name, kebab-cased,
  • category (string, optional): conditions can be grouped into categories available in the admin panel; if undefined, the condition will appear under the “Default” category,
  • plugin (string, optional): if the condition is created by a plugin, should be the plugin’s name, kebab-cased (e.g content-manager),
  • handler: a query object or a function used to verify the condition (see using the condition handler)

Declare and register conditions in your ./config/functions/bootstrap.js file (see Registering conditions).

NOTE

The condition name property acts as a unique id Configurations - 图32 (opens new window) within its namespace, that is either the plugin if the plugin property is defined, or the root namespace.

Using the condition handler

A condition can be applied to any permission, and the condition handler is used to verify the condition. The handler can be a query object or a function.

Query objects are useful to verify conditions on the entities you read, create, update, delete or publish. They use the sift.js Configurations - 图33 (opens new window) library, but only with the following supported operators:

  • $or
  • $eq
  • $ne
  • $in
  • $nin
  • $lt
  • $lte
  • $gt
  • $gte
  • $exists
  • $elemMatch

For instance, this handler uses a query object to match entities with an amount lower than 10,000:

  1. handler: { amount: { $lt: 10000 } }

The condition handler can also be a synchronous or asynchronous function that:

  • receives the authenticated user making the request,
  • and returns true, false, or a query object.

Returning true or false is useful to verify an external condition or a condition on the authenticated user. For instance, a condition that allows access to a page in the admin panel only if server time is 5pm could use this handler:

  1. handler: () => new Date().getHours() === 17

The handler function receives the authenticated user, so it can verify conditions on the user:

  1. const condition = {
  2. displayName: "Email address from strapi.io",
  3. name: "email-strapi-dot-io",
  4. async handler(user) {
  5. return user.email.includes('@strapi.io');
  6. },
  7. };

For more granular control, the handler function can also return a query object:

  1. const condition = {
  2. displayName: "price greater than 50",
  3. name: "price-gt-50",
  4. async handler(user) {
  5. return { price: { $gt: 50 } };
  6. },
  7. };

Registering conditions

To be available in the admin panel, conditions should be declared and registered in the ./config/functions/bootstrap.js file. Register a single condition with the conditionProvider.register() method:

  1. module.exports = () => {
  2. strapi.admin.services.permission.conditionProvider.register({
  3. displayName: 'Billing amount under 10K',
  4. name: 'billing-amount-under-10k',
  5. plugin: 'admin',
  6. handler: { amount: { $lt: 10000 }},
  7. });
  8. };

To register multiple conditions, defined as an array of condition objects, use conditionProvider.registerMany():

  1. const conditions = [
  2. {
  3. displayName: "Entity has same name as user",
  4. name: "same-name-as-user",
  5. plugin: "name of a plugin if created in a plugin"
  6. handler: (user) => {
  7. return { name: user.name };
  8. },
  9. },
  10. {
  11. displayName: "Email address from strapi.io",
  12. name: "email-strapi-dot-io",
  13. async handler(user) {
  14. return user.email.includes('@strapi.io');
  15. },
  16. }
  17. ];
  18. module.exports = () => {
  19. // do your boostrap
  20. strapi.admin.services.permission.conditionProvider.registerMany(conditions);
  21. };