This episode covers Astro configuration: the contents and options of astro.config.mjs, environment variables with import.meta.env, plugin and adapter integration, and build optimization and output path settings.

The bigger the project, the more important clean configuration becomes. Episode 8 covers the center of Astro's settings: the astro.config.mjs file, environment variables, plugin and adapter integration, and how to optimize the build and control the output path.
Configuration is often considered boring, yet it is where many production problems are born: leaked environment variables, wrong output, or an adapter that does not match the hosting. With proper understanding, you can prevent these problems before they happen.
This episode gives you the configuration foundation that will be used throughout the rest of the production phases of this series.
astro.config.mjs is the only configuration file that is required. Here is a fairly complete example:
import { defineConfig } from "astro/config";
import sitemap from "@astrojs/sitemap";
export default defineConfig({
site: "https://blog.contoh.dev",
base: "/blog",
output: "static",
integrations: [sitemap()],
});Options you will use often:
site: the canonical domain, used by the sitemap and canonical URLs.base: the path prefix if the site is hosted in a subfolder.output: static, server, or hybrid.integrations: the list of official integrations such as sitemap.base: "/blog" for example makes every route start with /blog — useful when placing the site in a hosting subdirectory.
Astro reads astro.config.mjs once at build. For different configurations across environments, you can use the --mode flag on the CLI, for example astro build --mode staging, and read the mode through import.meta.env.MODE in your code.
Environment variables prefixed with PUBLIC_ are accessible from client code and frontmatter. Store them in a .env file:
PUBLIC_API_URL=https://api.contoh.dev
PUBLIC_GA_ID=G-XXXXXXX
API_SECRET=rahasiabackendThen use them in code:
---
const apiUrl = import.meta.env.PUBLIC_API_URL;
---
<p>API berjalan di {apiUrl}</p>import.meta.env.PUBLIC_API_URL only reads variables prefixed with PUBLIC_. Variables without the prefix, such as API_SECRET, stay on the server side only and never leak into the client bundle.
Remember the important rule: everything prefixed with PUBLIC_ is shipped to the browser. Never put server API keys in a PUBLIC_-prefixed variable. In server mode, unprefixed variables can be read from import.meta.env because the code runs in the server runtime.
Also create a .env.example file listing the variables without real values, and make sure .env* is in .gitignore so secrets are never committed.
The safest way to add an integration is npx astro add, because the command updates astro.config.mjs and installs the dependencies at the same time:
npx astro add sitemap mdxnpx astro add sitemap mdx installs two integrations at once. Each integration is added to the integrations array, whose order determines the pipeline.
If your project uses output: "server" or "hybrid", you must choose an adapter that matches your hosting platform. The adapter transforms the build so it can run in that platform's runtime:
@astrojs/vercel for Vercel.@astrojs/netlify for Netlify.@astrojs/cloudflare for Cloudflare.@astrojs/node for general Node.js servers.import { defineConfig } from "astro/config";
import netlify from "@astrojs/netlify";
export default defineConfig({
output: "server",
adapter: netlify(),
});The adapter choice determines how deployment works and where serverless functions live — episode 20 will go deeper.
The default output folder is dist/. You can change it through the build options in astro.config.mjs:
export default defineConfig({
build: {
format: "directory",
inlineStylesheets: "auto",
},
trailingSlash: "ignore",
});format: "directory" produces extensionless URLs like /blog/posts/satu/.inlineStylesheets: "auto" inlines small CSS directly into the HTML.trailingSlash: "ignore" lets URLs with and without a trailing slash both work.After npm run build, check the contents of dist/. CSS is minified, HTML is ready to serve, and static assets are copied from public. For a static site, this folder can be uploaded to any hosting without extra steps.
Warning
After switching adapters, always re-run npm run build and inspect the dist folder to confirm the output matches your hosting platform — never change configuration without verifying the result.
Episode 8 equips you with solid configuration: the contents and options of astro.config.mjs, using environment variables with the PUBLIC_ rule, installing integrations and adapters, and optimizing the build and output path.
The key takeaways:
astro.config.mjs manages site, base, output, and integrations.PUBLIC_ variables are visible on the client; others stay on the server.import.meta.env is how you read environment variables.npx astro add is the safest way to add integrations.build options control URL format, CSS, and the output folder.In the next episode 9, we will cover images and asset optimization: responsive image optimization, asset and static file management, lazy loading media, and cache control and CDN integration. Images are the heaviest asset on the web — optimizing them has a huge impact.