MedusaGo Configurations
In this chapter, you'll learn about the general configurations in medusa-config.go, and the options you can set.
Configuration File#
The configuration of a MedusaGo application is a Go function that returns a config.InputConfig value. In a project created with create-medusago-app, it's the medusaConfig function in medusa-config.go, which main.go passes to the CLI:
import (
"os"
"github.com/hitkey-io/medusago/packages/core/framework/src/config"
)
// medusaConfig is the equivalent of medusa-config.ts. The CLI loads the .env
// files before calling it.
func medusaConfig() config.InputConfig {
return config.InputConfig{
ProjectConfig: config.ProjectConfig{
DatabaseURL: os.Getenv("DATABASE_URL"),
HTTP: config.HttpConfig{
StoreCors: os.Getenv("STORE_CORS"),
AdminCors: os.Getenv("ADMIN_CORS"),
AuthCors: os.Getenv("AUTH_CORS"),
JwtSecret: os.Getenv("JWT_SECRET"),
CookieSecret: os.Getenv("COOKIE_SECRET"),
},
},
}
}
The CLI loads the .env files before it calls medusaConfig, so you can read environment variables with os.Getenv.
The value you return is completed by config.DefineConfig. It fills the defaults described in this chapter, such as the fallbacks to environment variables, and merges the modules you add with MedusaGo's default modules. An option you leave empty takes its default.
The config.InputConfig struct has the following fields:
ProjectConfig: the project configurations.Admin: the admin configurations.Modules: the module configurations.Plugins: the plugin configurations.FeatureFlags: the feature flags.
Configuration Without Go Code#
A project made only of configuration doesn't need Go code. The stock CLI (the packages/cli/medusa-cli command of the MedusaGo repository) reads the same configuration from a medusa-config.json, medusa-config.yaml, or medusa-config.yml file in the working directory. The keys are the camelCase names used in the headings of this chapter, such as projectConfig and databaseUrl, except for is_default in a module provider.
Values in these files are literal: they aren't expanded with environment variables. The options that default to an environment variable (such as DATABASE_URL or JWT_SECRET) can be left out of the file and set in the environment instead.
Project Configurations (projectConfig)#
The ProjectConfig field holds the options of the server, the database, and the sessions. This example sets the most common ones:
return config.InputConfig{
ProjectConfig: config.ProjectConfig{
DatabaseURL: os.Getenv("DATABASE_URL"),
RedisURL: os.Getenv("REDIS_URL"),
RedisPrefix: "medusa:",
HTTP: config.HttpConfig{
StoreCors: os.Getenv("STORE_CORS"),
AdminCors: os.Getenv("ADMIN_CORS"),
AuthCors: os.Getenv("AUTH_CORS"),
JwtSecret: os.Getenv("JWT_SECRET"),
CookieSecret: os.Getenv("COOKIE_SECRET"),
JwtExpiresIn: "7d",
StoreRelationsLimit: 3,
},
},
}
databaseUrl#
The databaseUrl configuration (Go field ProjectConfig.DatabaseURL) is the PostgreSQL connection URL of your application. If you leave it empty, MedusaGo uses the DATABASE_URL environment variable.
return config.ProjectConfig{
DatabaseURL: "postgres://postgres:postgres@localhost/medusa-store",
}
The URL is passed as it is to the pgx driver, so it accepts the connection parameters that pgx supports, such as sslmode and pool_max_conns. For example: postgres://user:password@host:5432/medusa?sslmode=require.
redisUrl#
The redisUrl configuration (Go field ProjectConfig.RedisURL) is the connection URL of a Redis server that stores the server's sessions. When it's empty, sessions are kept in the server's memory, which means they're lost when the server restarts and aren't shared between instances.
MedusaGo doesn't read REDIS_URL on its own: set RedisURL from the environment variable in medusa-config.go, as the example above does. This option only configures sessions. The Redis-based modules take their own Redis URL, so you pass it to each module.
redisPrefix#
The redisPrefix configuration (Go field ProjectConfig.RedisPrefix) is a prefix for the keys of the sessions in Redis. The session keys have the format <prefix>sess:<session id>.
redisOptions#
The redisOptions configuration (Go field ProjectConfig.RedisOptions) is a map[string]any of Redis client options, such as connectTimeout, applied on top of the values in redisUrl.
http#
The HTTP field of ProjectConfig holds the options of the HTTP layer.
http.jwtSecret
The http.jwtSecret configuration (Go field HTTP.JwtSecret) is a secret used to sign the authentication tokens of the HTTP layer. If you leave it empty, MedusaGo uses the JWT_SECRET environment variable, and supersecret if that isn't set either.
supersecret default. Always set a random secret in production.http.jwtExpiresIn
The http.jwtExpiresIn configuration (Go field HTTP.JwtExpiresIn) is how long an authentication token is valid. It's a string such as 10h, 7d, or 60s, or a number of seconds. The default is 1d.
http.cookieSecret
The http.cookieSecret configuration (Go field HTTP.CookieSecret) is a secret used to sign the session cookie. If you leave it empty, MedusaGo uses the COOKIE_SECRET environment variable, and supersecret if that isn't set either. Set a random value in production.
http.authCors
The http.authCors configuration (Go field HTTP.AuthCors) is a comma-separated list of the origins that can send requests to the /auth routes. If you leave it empty, MedusaGo uses the AUTH_CORS environment variable, and http://localhost:7000,http://localhost:7001,http://localhost:5173 if that isn't set either.
Each item is either an origin, or a regular expression written between slashes. The expression uses Go's regular expression syntax and can end with the flags i, m, or s.
return config.HttpConfig{
StoreCors: "http://localhost:8000,https://storefront.example.com",
AdminCors: "http://localhost:9000,/vercel\\.app$/",
AuthCors: "http://localhost:8000,http://localhost:9000",
}
http.storeCors
The http.storeCors configuration (Go field HTTP.StoreCors) is a comma-separated list of the origins of storefronts that can send requests to the Store API routes. It accepts the same formats as authCors. If you leave it empty, MedusaGo uses the STORE_CORS environment variable, and http://localhost:8000 if that isn't set either.
http.adminCors
The http.adminCors configuration (Go field HTTP.AdminCors) is a comma-separated list of the origins of admin dashboards that can send requests to the Admin API routes. It accepts the same formats as authCors. If you leave it empty, MedusaGo uses the ADMIN_CORS environment variable, and http://localhost:7000,http://localhost:7001,http://localhost:5173 if that isn't set either.
/app sends requests to the server's own origin. Add its URL to adminCors and authCors if you open the dashboard from an origin that's different from the server's.http.authMethodsPerActor
The http.authMethodsPerActor configuration (Go field HTTP.AuthMethodsPerActor) is a map[string][]string that lists the IDs of the auth providers each actor type can authenticate with. The default for the user actor type is emailpass.
return config.HttpConfig{
AuthMethodsPerActor: map[string][]string{
"user": {"emailpass", "google"},
"customer": {"emailpass"},
},
}
http.requireActorAssociation
The http.requireActorAssociation configuration (Go field HTTP.RequireActorAssociation) is a map[string]bool whose keys are auth provider IDs. When it's true for a provider, the provider only authenticates auth identities that are already associated with an actor of the requested actor type. By default, an auth identity can authenticate as any actor type.
http.restrictedFields
The http.restrictedFields configuration (Go field HTTP.RestrictedFields.Store) lists the fields that can't be selected in Store API routes with the fields query parameter, unless the route allows them. The default is order and orders.
http.storeRelationsLimit
The http.storeRelationsLimit configuration (Go field HTTP.StoreRelationsLimit) is the maximum number of relations a caller can expand in a single request to a Store API route. For example, requesting variants.options.values expands three relations. The default is 3.
sessionOptions#
The sessionOptions configuration (Go field ProjectConfig.SessionOptions, a pointer) customises the session middleware. It has the following fields:
Field | Description | Default |
|---|---|---|
| The name of the session cookie. |
|
| Whether to save the session to the store on every request, even when it didn't change. |
|
| Whether to renew the cookie's expiry on every response. |
|
| Whether to save sessions that haven't been modified. |
|
| The secret used to sign the session cookie. | The value of |
| The lifetime of the session cookie, in milliseconds. |
|
| A | - |
The Resave, Rolling, SaveUninitialized, and Ttl fields are pointers, so you can tell an unset value from false or zero. In Go 1.26 and later, you can write new(true) to get a pointer to a value.
cookieOptions#
The cookieOptions configuration (Go field ProjectConfig.CookieOptions, a pointer) customises the session cookie. It has the following fields: Secure, SameSite, Domain, Path, HttpOnly, MaxAge (in milliseconds), Partitioned, and Priority.
When NODE_ENV is production or staging, the cookie is Secure and SameSite=lax by default, and the server only sets it on requests that arrive over HTTPS. Read the Build chapter to learn how this affects running a production build locally.
return config.ProjectConfig{
RedisURL: os.Getenv("REDIS_URL"),
RedisPrefix: "medusa:",
SessionOptions: &config.SessionOptions{
Name: "connect.sid",
Secret: os.Getenv("COOKIE_SECRET"),
// Ttl is the lifetime of the session cookie in milliseconds.
Ttl: new(int64(10 * 60 * 60 * 1000)),
Resave: new(true),
Rolling: new(false),
},
CookieOptions: &config.CookieOptions{
SameSite: "lax",
Secure: new(true),
Domain: ".example.com",
},
}
workerMode, databaseDriverOptions, databaseLogging, databaseName, jwtOptions, jwtPublicKey, jwtVerifyOptions, authVerificationsPerActor, and compression options of Medusa's configuration are not supported by MedusaGo. Set the worker mode with the MEDUSA_WORKER_MODE environment variable instead.Admin Configurations (admin)#
The Admin field of config.InputConfig configures the Medusa Admin that the server serves. Its fields are pointers, so an unset field takes its default.
return config.InputConfig{
Admin: config.AdminInput{
Disable: new(false),
Path: new("/app"),
BackendURL: new(os.Getenv("MEDUSA_BACKEND_URL")),
StorefrontURL: new("https://storefront.example.com"),
MaxUploadFileSize: new(float64(5 * 1024 * 1024)),
},
}
Unlike Medusa, MedusaGo applies these options when the server starts, not when you build. You can change them and restart the server without rebuilding the admin.
backendUrl#
The admin.backendUrl configuration (Go field Admin.BackendURL) is the URL the dashboard sends API requests to. If you leave it unset, MedusaGo uses the MEDUSA_BACKEND_URL environment variable, and / (the server serving the dashboard) if that isn't set either.
Set it only when the dashboard and the API are served from different origins.
disable#
The admin.disable configuration (Go field Admin.Disable) disables serving the dashboard. It's useful in a worker deployment, where you can set it from an environment variable:
return config.InputConfig{
Admin: config.AdminInput{
Disable: new(os.Getenv("DISABLE_MEDUSA_ADMIN") == "true"),
},
}
path#
The admin.path configuration (Go field Admin.Path) is the path the dashboard is served at. The default is /app. It shouldn't be /auth, /store, or /admin, since the APIs use those paths. The server logs an error if you set one of them.
storefrontUrl#
The admin.storefrontUrl configuration (Go field Admin.StorefrontURL) is the URL of your storefront. The dashboard uses it to link to storefront pages.
maxUploadFileSize#
The admin.maxUploadFileSize configuration (Go field Admin.MaxUploadFileSize) is the maximum size, in bytes, of a file that the dashboard accepts for upload. The default is 1048576 (1 MiB). Use math.Inf(1) for no limit.
Admin.OutDir is accepted for compatibility with Medusa's configuration but has no effect. The server and the build always use public/admin (or .medusa/admin for build --admin-only). The admin.vite option isn't supported.Module Configurations (modules)#
The Modules field of config.InputConfig is a list of config.ModuleConfig values. MedusaGo starts with a default list of modules, and the modules you add either replace the default one with the same key or are added to the list.
A config.ModuleConfig has the following fields:
Key: the module's key, such aslocking. When you leave it empty, MedusaGo derives it fromResolvefor MedusaGo's own modules, and from the module's definition for custom modules.Resolve: the module's package name, such as@medusajs/medusa/event-bus-redis. For a module of your project, setModuleto its definition instead.Options: amap[string]anyof the module's options.Providers: the module providers, each withResolve,ID,Options, andIsDefault. Modules that support providers, such as the File and Locking Modules, take them here.Disable: whether to disable the module.Module: the module definition of a custom module of your project.
For example, this replaces the in-process Event Module and the in-memory Workflow Engine, Locking, and Caching Modules with their Redis implementations:
redisURL := os.Getenv("REDIS_URL")
return []config.ModuleConfig{
{
Resolve: "@medusajs/medusa/event-bus-redis",
Options: map[string]any{"redisUrl": redisURL},
},
{
Resolve: "@medusajs/medusa/workflow-engine-redis",
Options: map[string]any{
"redis": map[string]any{"redisUrl": redisURL},
},
},
{
Key: "locking",
Resolve: "@medusajs/medusa/locking",
Providers: []config.ModuleProviderConfig{
{
Resolve: "@medusajs/medusa/locking-redis",
ID: "locking-redis",
IsDefault: true,
Options: map[string]any{"redisUrl": redisURL},
},
},
},
{
Key: "caching",
Resolve: "@medusajs/medusa/caching",
Providers: []config.ModuleProviderConfig{
{
Resolve: "@medusajs/medusa/caching-redis",
ID: "caching-redis",
IsDefault: true,
Options: map[string]any{"redisUrl": redisURL},
},
},
},
}
redis option, as shown above. In the others, it's the redisUrl option.To pass the list to your configuration:
This example replaces the local File Module Provider with the S3 provider, which stores files in a bucket instead of the server's disk:
return config.ModuleConfig{
Key: "file",
Resolve: "@medusajs/medusa/file",
Providers: []config.ModuleProviderConfig{
{
Resolve: "@medusajs/medusa/file-s3",
ID: "s3",
IsDefault: true,
Options: map[string]any{
"file_url": os.Getenv("S3_FILE_URL"),
"access_key_id": os.Getenv("S3_ACCESS_KEY_ID"),
"secret_access_key": os.Getenv("S3_SECRET_ACCESS_KEY"),
"region": os.Getenv("S3_REGION"),
"bucket": os.Getenv("S3_BUCKET"),
"endpoint": os.Getenv("S3_ENDPOINT"),
},
},
},
}
Learn how to register your own module in the Modules chapter.
Plugin Configurations (plugins)#
The Plugins field of config.InputConfig lists the plugins to enable. A plugin is a Go package that registers itself when it's imported, so you also need to import it in main.go. The stock CLI already links in the official loyalty plugin.
return config.InputConfig{
Plugins: []config.PluginConfig{
{Resolve: "@medusajs/loyalty-plugin", Options: map[string]any{}},
},
}
Learn more in the Plugins chapter.
Feature Flags (featureFlags)#
The FeatureFlags field is a map[string]any that toggles feature flags. Its keys are the flags' keys, and its values are booleans.