Documents
admin-panel
admin-panel
Type
External
Status
Published
Created
Mar 5, 2026
Updated
Mar 5, 2026

Admin panel configuration#

Options in `/config/admin` let you tweak admin panel behavior and server settings, including custom URLs, host, and port.

The /config/admin file is used to define the admin panel configuration for the Strapi application.

The present page acts as a reference for all the configuration parameters and values that you can find in the /config/admin file, grouped by topic. For additional information on how each feature works, please refer to links given in the introduction of each sub-section.

Admin panel behavior#

The admin panel behavior can be configured with the following parameters:

ParameterDescriptionTypeDefault
autoOpenEnable or disable administration opening on start.booleantrue
watchIgnoreFilesAdd custom files that should not be watched during development.

See more (property ignored).
array(string)[]
serveAdminPanelIf false, the admin panel won't be served.

Note: the index.html will still be served
booleantrue

:::note config/admin vs. src/admin/app configurations
Some UI elements of the admin panel must be configured in the src/admin/app file:

Tutorial videos
To disable the information box containing the tutorial videos, set the config.tutorials key to false.

Releases notifications
To disable notifications about new Strapi releases, set the config.notifications.releases key to false.

const config = {
  // … other customization options go here
  tutorials: false,
  notifications: { releases: false },
};

export default {
  config,
};

:::

Admin panel server#

By default, Strapi's admin panel is exposed via http://localhost:1337/admin. For security reasons, the host, port, and path can be updated.

The server configuration for the admin panel can be configured with the following parameters:

ParameterDescriptionTypeDefault
urlPath to access the admin panel. If the URL is relative, it will be concatenated with the server URL.

Example: /dashboard makes the admin panel accessible at http://localhost:1337/dashboard.
string/admin
hostHost for the admin panel server.stringlocalhost
portPort for the admin panel server.string8000

Update the admin panel's path only#

To make the admin panel accessible at another path, for instance at http://localhost:1337/dashboard, define or update the url property:

module.exports = ({ env }) => ({
  // … other configuration properties
  url: "/dashboard",
});

Since by default the back-end server and the admin panel server run on the same host and port, only updating the config/admin file should work if you left the host and port property values untouched in the back-end server configuration file.

Update the admin panel's host and port#

If the admin panel server and the back-end server are not hosted on the same server, you will need to update the host and port of the admin panel. For example, to host the admin panel on my-host.com:3000:

module.exports = ({ env }) => ({
  host: "my-host.com",
  port: 3000,
  // Additionally you can define another path instead of the default /admin one 👇
  // url: '/dashboard' 
});
export default ({ env }) => ({
  host: "my-host.com",
  port: 3000,
  // Additionally you can define another path instead of the default /admin one 👇
  // url: '/dashboard'
});

Trust additional hosts during development#

When you run strapi develop, the admin panel is served through a Vite development server that Strapi boots in middleware mode and proxies through the Koa app. By default, Vite validates the Host header against a small set of safe values. Requests that do not match are rejected with an "Invalid Host" response, which prevents you from previewing the admin panel when it is reached through a tunnel, reverse proxy, or custom domain. Strapi exposes Vite's server.allowedHosts option so that you can extend that allowlist when necessary.

How Strapi loads custom Vite configuration#

During development Strapi builds a base Vite configuration, then tries to load a user-supplied config from ./src/admin/vite.config.{js,ts,mjs}. If the file exports a function it is invoked with the base configuration and Strapi uses the returned value. The project templates ship with an example file that simply merges a custom alias into the provided configuration, which is a good starting point for your own overrides.

Allow additional hosts#

Create ./src/admin/vite.config.ts (or .js) if it does not already exist and extend the dev-server configuration. The following example snippet adds 2 custom domains while keeping the rest of Strapi's defaults untouched:

import { mergeConfig } from 'vite';

export default (config) => {
  return mergeConfig(config, {
    server: {
      allowedHosts: ['preview.my-app.test', '.example-proxy.internal'],
    },
  });
};
import { mergeConfig, type UserConfig } from 'vite';

export default (config: UserConfig) => {
  return mergeConfig(config, {
    server: {
      allowedHosts: ['preview.my-app.test', '.example-proxy.internal'],
    },
  });
};

A few tips while configuring allowedHosts:

  • Pass a string array or 'all', matching Vite's accepted shapes.
  • Leading dots (.example.com) allow any subdomain.
  • Combine this option with Strapi's existing hmr.clientPort setting when accessing the admin panel through tunnels that rewrite ports.

After saving the file, restart strapi develop. Vite will now trust requests whose Host header matches the entries you provided, so proxied or tunneled URLs will load without triggering host validation errors.

Deploy on different servers {#deploy-on-different-servers}#

Unless you chose to deploy Strapi's back-end server and admin panel server on different servers, by default:

  • The back-end server and the admin panel server both run on the same host and port (http://localhost:1337/)
  • The admin panel is accessible at the /admin path while the back-end server is accessible at the /api path

To deploy the admin panel and the back-end on completely different servers, you need to configure both the server (/config/server) and admin panel (/config/admin-panel) configurations.

The following example setup allows you to serve the admin panel from one domain while the API runs on another:

module.exports = ({ env }) => ({
  host: env("HOST", "0.0.0.0"),
  port: env.int("PORT", 1337),
  url: "http://yourbackend.com",
});
module.exports = ({ env }) => ({
  /**
   * Note: The administration will be accessible from the root of the domain 
   * (ex: http://yourfrontend.com/)
   */ 
  url: "/",
  serveAdminPanel: false, // http://yourbackend.com will not serve any static admin files
});
export default ({ env }) => ({
  host: env("HOST", "0.0.0.0"),
  port: env.int("PORT", 1337),
  url: "http://yourbackend.com",
});
export default ({ env }) => ({
  /**
   * Note: The administration will be accessible from the root of the domain 
   * (ex: http://yourfrontend.com/)
   */ 
  url: "/",
  serveAdminPanel: false, // http://yourbackend.com will not serve any static admin files
});

With this configuration:

  • The admin panel will be accessible at http://yourfrontend.com
  • All API requests from the panel will be sent to http://yourbackend.com
  • The backend server will not serve any static admin files due to serveAdminPanel: false

API tokens#

The API tokens feature can be configured with the following parameters:

ParameterDescriptionTypeDefault
apiToken.saltSalt used to generate API tokensstringRandom string
apiToken.secrets.encryptionKeyEncryption key used to set API tokens visibility in the admin panelstringRandom string

Audit logs#

The Audit Logs feature can be configured with the following parameters:

ParameterDescriptionTypeDefault
auditLogs.enabledEnable or disable the Audit Logs featurebooleantrue
auditLogs.retentionDaysHow long Audit Logs are kept, in days.

The behavior differs for self-hosted vs. Strapi Cloud customers, see the note under the table.
integer90

:::note Retention days for self-hosted vs. Strapi Cloud users
For Strapi Cloud customers, the auditLogs.retentionDays value stored in the license information is used, unless a smaller retentionDays value is defined in the config/admin.js|ts configuration file.
:::

Authentication#

The authentication system, including SSO configuration and session management, can be configured with the following parameters:

Basic authentication#

To configure basic authentication, use the following parameters:

ParameterDescriptionTypeDefault
authAuthentication configurationobject-
auth.secretSecret used to encode JWT tokensstringundefined
auth.domainDomain used within the cookie for SSO authentication )stringundefined
auth.providersList of authentication providers used for SSOarray(object)-
auth.optionsOptions object passed to jsonwebtokenobject-
auth.options.expiresInJWT expire time used in jsonwebtokenobject30d
auth.eventsRecord of all the events subscribers registered for the authenticationobject{}
auth.events.onConnectionSuccessFunction called when an admin user log in successfully to the administration panelfunctionundefined
auth.events.onConnectionErrorFunction called when an admin user fails to log in to the administration panelfunctionundefined

Additional configuration parameters are available for session management.

Session management#

Admin authentication uses session management by default for enhanced security.

Session management provides enhanced security for authentication in Strapi applications by using short-lived access tokens paired with longer-lived refresh tokens. This approach reduces the risk of token theft and allows for more granular control over user sessions.

:::caution Serve the admin panel over HTTPS
Since v5.24.0, Strapi stores admin authentication data in secure, HTTP-only cookies. Browsers only accept and send these cookies over HTTPS connections, so attempting to access the admin panel via plain HTTP prevents the session cookie from being set and results in failed logins. Always expose the admin panel through HTTPS in production (for example, by placing Strapi behind a TLS-terminating proxy or load balancer). Local development continues to work with the default configuration because cookies are not marked as secure in that environment.
:::

Strapi's session management system supports both admin panel authentication and Content API authentication through the Users & Permissions feature. The system provides:

  • Short-lived access tokens (typically 30 minutes) for API requests
  • Refresh tokens for obtaining new access tokens
  • Device-specific sessions for targeted logout
  • Configurable token lifespans for different security requirements

To configure session lifespans and behavior, use the following parameters:

ParameterDescriptionTypeDefault
auth.sessionsSession management configurationobject{}
auth.sessions.accessTokenLifespanAccess token lifespan in secondsnumber1800 (30 minutes)
auth.sessions.maxRefreshTokenLifespanMaximum refresh token lifespan in secondsnumber2592000 (30 days, or legacy expiresIn value)
auth.sessions.idleRefreshTokenLifespanIdle refresh token timeout in secondsnumber604800 (7 days)
auth.sessions.maxSessionLifespanMaximum session duration in secondsnumber2592000 (30 days, or legacy expiresIn value)
auth.sessions.idleSessionLifespanSession idle timeout in secondsnumber3600 (1 hour)

To configure HTTP cookies for admin authentication, use the following parameters:

ParameterDescriptionTypeDefault
auth.cookieCookie configuration for admin authenticationobject{}
auth.cookie.domainCookie domain (inherits from server if not set)stringundefined
auth.cookie.pathCookie pathstring'/admin'
auth.cookie.sameSitestring'lax'

Feature flags#

The feature flags can be configured with the following parameters:

ParameterDescriptionTypeDefault
flagsSettings to turn certain features or elements of the admin on or offobject{}
flags.npsEnable/Disable the Net Promoter Score popupbooleantrue
flags.promoteEEEnable/Disable the promotion of Strapi Enterprise featuresbooleantrue

Forgot password#

The forgot password functionality, including email templating, can be configured with the following parameters:

ParameterDescriptionTypeDefault
forgotPasswordSettings to customize the forgot password emailobject{}
forgotPassword.emailTemplateEmail template as defined in email pluginobjectDefault template
forgotPassword.fromSender mail addressstringDefault value defined in
your provider configuration
forgotPassword.replyToDefault address or addresses the receiver is asked to reply tostringDefault value defined in
your provider configuration

Rate limiting#

The rate limiting for the admin panel's authentication endpoints can be configured with the following parameters. Additional configuration options come from the package:

ParameterDescriptionTypeDefault
rateLimitSettings to customize the rate limiting of the admin panel's authentication endpointsobject{}
rateLimit.enabledEnable or disable the rate limiterbooleantrue
rateLimit.intervalTime window for requests to be considered as part of the same rate limiting bucketobject{ min: 5 }
rateLimit.maxMaximum number of requests allowed in the time windowinteger5
rateLimit.delayAfterNumber of requests allowed before delaying responsesinteger1
rateLimit.timeWaitTime to wait before responding to a request (in milliseconds)integer3000
rateLimit.prefixKeyPrefix for the rate limiting keystring${userEmail}:${ctx.request.path}:${ctx.request.ip}
rateLimit.whitelistArray of IP addresses to whitelist from rate limitingarray(string)[]
rateLimit.storeRate limiting storage location (Memory, Sequelize, or Redis). For more information see the koa2-ratelimit documentationobjectMemoryStore

Strapi AI {#strapi-ai}#

Strapi AI, adding features to the Content-Type Builder and Media Library with plans, can be enabled or disabled:

ParameterDescriptionTypeDefault
ai.enabledWhether Strapi AI is enabled or notbooleantrue

Transfer tokens#

Transfer tokens for the Data transfer feature can be configured with the following parameters:

ParameterDescriptionTypeDefault
transfer.token.saltSalt used to generate Transfer tokens.

If no transfer token salt is defined, transfer features will be disabled.
stringa random string

:::note Retention days for self-hosted vs. Strapi Cloud users
For Strapi Cloud customers, the auditLogs.retentionDays value stored in the license information is used, unless a smaller retentionDays value is defined in the config/admin.js|ts configuration file.
:::

Configuration examples#

The /config/admin file should at least include a minimal configuration with required parameters for authentication and API tokens. Additional parameters can be included for a full configuration.

The default configuration created with any new project should at least include the following:

module.exports = ({ env }) => ({
  apiToken: {
    salt: env('API_TOKEN_SALT', 'someRandomLongString'),
  },
  auditLogs: { // only accessible with an Enterprise plan
    enabled: env.bool('AUDIT_LOGS_ENABLED', true),
  },
  auth: {
    secret: env('ADMIN_JWT_SECRET', 'someSecretKey'),
  },
  transfer: { 
    token: { 
      salt: env('TRANSFER_TOKEN_SALT', 'anotherRandomLongString'),
    } 
  },
});


export default ({ env }) => ({
  apiToken: {
    salt: env('API_TOKEN_SALT', 'someRandomLongString'),
  },
   auditLogs: { // only accessible with an Enterprise plan
    enabled: env.bool('AUDIT_LOGS_ENABLED', true),
  },
  auth: {
    secret: env('ADMIN_JWT_SECRET', 'someSecretKey'),
  },
  transfer: { 
    token: { 
      salt: env('TRANSFER_TOKEN_SALT', 'anotherRandomLongString'),
    } 
  },
});

module.exports = ({ env }) => ({
  apiToken: {
    salt: env('API_TOKEN_SALT', 'someRandomLongString'),
    secrets: {
      encryptionKey: env('ENCRYPTION_KEY'),
    },
  },
  ai: {
    enabled: false, // use this to disable Strapi AI
  },
  auditLogs: { // only accessible with an Enterprise plan
    enabled: env.bool('AUDIT_LOGS_ENABLED', true),
    retentionDays: 120,
  },
  auth: {
    events: {
      onConnectionSuccess(e) {
        console.log(e.user, e.provider);
      },
      onConnectionError(e) {
        console.error(e.error, e.provider);
      },
    },
    options: {
      expiresIn: '7d',
    },
    secret: env('ADMIN_JWT_SECRET', 'someSecretKey'),
    sessions: {
      accessTokenLifespan: 1800, // 30 minutes
      maxRefreshTokenLifespan: 2592000, // 30 days
      idleRefreshTokenLifespan: 604800, // 7 days
      maxSessionLifespan: 604800, // 7 days
      idleSessionLifespan: 3600, // 1 hour
    },
    cookie: {
      domain: env('ADMIN_COOKIE_DOMAIN'),
      path: '/admin',
      sameSite: 'lax',
    },
  },
  url: env('PUBLIC_ADMIN_URL', '/dashboard'),
  autoOpen: false,
  watchIgnoreFiles: [
    './my-custom-folder', // Folder
    './scripts/someScript.sh', // File
  ],
  host: 'localhost',
  port: 8003,
  serveAdminPanel: env.bool('SERVE_ADMIN', true),
  forgotPassword: {
    from: 'no-reply@example.com',
    replyTo: 'no-reply@example.com',
  },
  rateLimit: {
    interval: { hour: 1, min: 30 },
    timeWait: 3*1000,
    max: 10,
  },
  transfer: { 
    token: { 
      salt: env('TRANSFER_TOKEN_SALT', 'anotherRandomLongString'),
    } 
  },
});


export default ({ env }) => ({
  apiToken: {
    salt: env('API_TOKEN_SALT', 'someRandomLongString'),
    secrets: {
      encryptionKey: env('ENCRYPTION_KEY'),
    },
  },
  ai: {
    enabled: false, // use this to disable Strapi AI
  },
  auditLogs: { // only accessible with an Enterprise plan
    enabled: env.bool('AUDIT_LOGS_ENABLED', true),
    retentionDays: 120,
  },
  auth: {
    events: {
      onConnectionSuccess(e) {
        console.log(e.user, e.provider);
      },
      onConnectionError(e) {
        console.error(e.error, e.provider);
      },
    },
    options: {
      expiresIn: '7d',
    },
    secret: env('ADMIN_JWT_SECRET', 'someSecretKey'),
    sessions: {
      accessTokenLifespan: 1800, // 30 minutes
      maxRefreshTokenLifespan: 2592000, // 30 days
      idleRefreshTokenLifespan: 604800, // 7 days
      maxSessionLifespan: 604800, // 7 days
      idleSessionLifespan: 3600, // 1 hour
    },
    cookie: {
      domain: env('ADMIN_COOKIE_DOMAIN'),
      path: '/admin',
      sameSite: 'lax',
    },
  },
  url: env('PUBLIC_ADMIN_URL', '/dashboard'),
  autoOpen: false,
  watchIgnoreFiles: [
    './my-custom-folder', // Folder
    './scripts/someScript.sh', // File
  ],
  host: 'localhost',
  port: 8003,
  serveAdminPanel: env.bool('SERVE_ADMIN', true),
  forgotPassword: {
    from: 'no-reply@example.com',
    replyTo: 'no-reply@example.com',
  },
  rateLimit: {
    interval: { hour: 1, min: 30 },
    timeWait: 3*1000,
    max: 10,
  },
  transfer: { 
    token: { 
      salt: env('TRANSFER_TOKEN_SALT', 'anotherRandomLongString'),
    } 
  },
});