This astro.config.mjs cheatsheet covers the options you’ll actually set on a production Astro 7 site, grouped by job, with the default and a one-line example for each. Every option lives in the object passed to defineConfig() in astro.config.mjs at the project root. Add // @ts-check at the top of the file and your editor will validate keys and values as you type.
Key Takeaways
- Set
sitefirst: sitemaps, canonical URLs and RSS depend on it.outputdefaults to'static'; add anadapteronly for on-demand pages.trailingSlashandbuild.formattogether decide your URL shape.image,fontsandprefetchare the highest-value performance options.
A complete starting config
// @ts-check
// astro.config.mjs
import { defineConfig, fontProviders } from 'astro/config';
import mdx from '@astrojs/mdx';
import sitemap from '@astrojs/sitemap';
export default defineConfig({
site: 'https://www.example.com',
trailingSlash: 'always',
build: { format: 'directory' },
integrations: [mdx(), sitemap()],
image: { layout: 'constrained', responsiveStyles: true },
fonts: [{ provider: fontProviders.google(), name: 'Inter', cssVariable: '--font-inter' }],
prefetch: true,
});
Site and URLs
| Option | Default | Example | Notes |
|---|---|---|---|
site |
none | 'https://www.example.com' |
Production origin; used for absolute URLs |
base |
'/' |
'/docs' |
Serve from a subpath (GitHub Pages project sites) |
trailingSlash |
'ignore' |
'always' |
'always', 'never' or 'ignore' |
build.format |
'directory' |
'file' |
about/index.html vs about.html |
redirects |
{} |
{ '/old/': '/new/' } |
See redirects in Astro |
The interaction between the two URL options is explained in trailingSlash and build.format.
Rendering and hosting
| Option | Default | Example |
|---|---|---|
output |
'static' |
'server' |
adapter |
none | netlify() |
server.port |
4321 |
3000 |
server.host |
false |
true (listen on all addresses) |
output: 'static' still allows individual on-demand pages with export const prerender = false once an adapter is set. See the Astro SSR guide.
Build
| Option | Default | Purpose |
|---|---|---|
outDir |
'./dist' |
Where the build is written |
publicDir |
'./public' |
Files copied as-is |
cacheDir |
'./node_modules/.astro' |
Image and content cache; cache it in CI |
build.inlineStylesheets |
'auto' |
'always', 'auto' or 'never' |
build.concurrency |
1 |
Pages built in parallel |
build.assets |
'_astro' |
Folder name for hashed assets |
compressHTML |
'jsx' |
Since Astro 7, JSX whitespace rules; true minifies, false keeps source whitespace |
Astro 7’s 'jsx' default removes whitespace and line breaks around elements, like React does. If two inline elements lose the space between them, add it explicitly with {" "} in the template.
Images
image: {
layout: 'constrained', // default layout for <Image /> and Markdown images
responsiveStyles: true, // add CSS so responsive images size correctly
domains: ['images.example-cms.com'],
remotePatterns: [{ protocol: 'https', hostname: '**.cdn.example.com' }],
},
Remote images from other hosts are rejected; see Remote image is not allowed.
Fonts
fonts: [
{ provider: fontProviders.google(), name: 'Inter', cssVariable: '--font-inter', weights: [400, 700] },
],
Pair with <Font cssVariable="--font-inter" preload /> in your layout.
Prefetch
prefetch: true, // opt-in per link
prefetch: { prefetchAll: true, defaultStrategy: 'hover' },
Strategies: 'hover', 'tap', 'viewport', 'load'. See prefetch links in Astro.
i18n
i18n: {
locales: ['en', 'fr'],
defaultLocale: 'en',
routing: { prefixDefaultLocale: false },
},
Environment variables
import { envField } from 'astro/config';
env: {
schema: {
PUBLIC_SITE_NAME: envField.string({ context: 'client', access: 'public' }),
API_KEY: envField.string({ context: 'server', access: 'secret' }),
},
},
Markdown
markdown: {
shikiConfig: { themes: { light: 'github-light', dark: 'github-dark' } },
remarkPlugins: [],
rehypePlugins: [],
},
MDX inherits these unless you set extendMarkdownConfig: false on mdx().
Sessions and security (on-demand sites)
import { sessionDrivers } from 'astro/config';
session: { driver: sessionDrivers.redis({ url: process.env.REDIS_URL }) },
security: { checkOrigin: true },
Vite passthrough
vite: {
plugins: [],
css: { preprocessorOptions: { scss: { additionalData: '@use "/src/styles/tokens" as *;\n' } } },
},
Dev toolbar
devToolbar: { enabled: false },
The Astro configuration docs show how a Komal theme’s config is organised, and the full option list with types is in the configuration reference.
FAQ
Do I need to restart the dev server after editing astro.config.mjs?
Astro restarts the server automatically when it detects config changes in most cases. Restart manually if an integration change doesn’t take effect.
Can astro.config.mjs read environment variables?
Yes. It runs in Node, so process.env works. Use loadEnv from Vite if you need values from .env files there.