Jesse A. Green / notebook

Astro — Administrator & Developer Guide

Generated May 2026 from withastro/astro at 1058428

AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it.

Astro is a modern web framework purpose-built for content-driven websites. Its defining characteristic is zero JavaScript shipped to the client by default — a philosophy enforced by its Islands Architecture, where interactive components are explicitly opted into client-side hydration. The framework is distributed as a TypeScript monorepo with over 6,100 files, maintained by the withastro organization and built around a core package (packages/astro/) surrounded by official integrations, language tooling, and shared utilities.

This guide covers architecture, configuration, deployment, security, and internals for administrators, platform engineers, and contributors working at the framework level.


1. Architecture Overview

1.1 High-Level Request Pipeline

Astro's runtime is structured as a layered pipeline that handles both development and production requests through a common abstract base, then specializes at the edges.

CLI (yargs-parser)
    │
    ▼
Config Resolution (Zod v4 validation)
    │
    ▼
Vite Dev Server  ─────────────────────────  Build (AppPipeline)
    │                                              │
    ▼                                              ▼
DevPipeline                               AppPipeline
    │                                              │
    └──────────────┬────────────────────────────── ┘
                   ▼
           RenderContext (per-request)
           ├── Middleware chain (sequence())
           ├── Actions (defineAction)
           ├── Sessions (driver-based)
           ├── Cache (provider-based)
           └── Routing (file-based + redirects)

The Pipeline abstract class in packages/astro/src/core/base-pipeline.ts defines this contract. AppPipeline in packages/astro/src/core/app/pipeline.ts is the production implementation. During development, an equivalent dev pipeline is used; they share the same RenderContext instantiation and middleware sequencing logic.

Important

The output: "hybrid" mode was removed in a prior major release. The only valid values for output are "static" (default) and "server". Any configuration referencing "hybrid" must be migrated before upgrading.

1.2 Class Hierarchy

Pipeline (abstract)
└── AppPipeline

BaseApp
└── App
    └── NodeApp

AstroError (extends Error)
├── CompilerError
├── CSSError
├── MarkdownError
├── InternalError
└── AggregateError

AstroUserError (extends Error — separate hierarchy)
MarkdocError (extends Error)
BodySizeLimitError (extends Error)

AstroTelemetry
GlobalConfig
AstroCheck
RouteCache
NodePool
HTMLStringCache
RenderContext

NodeApp in packages/astro/src/core/app/node.ts extends App with Node.js-specific adapter helpers, including BodySizeLimitError handling for oversized request bodies.

1.3 Vite Environment Model

Astro uses Vite as its build and dev-server foundation, and defines four named Vite environments:

Environment When Used Purpose
ssr Build and dev Server-side rendering of pages and endpoints
client Build Client-side JavaScript bundles shipped to browsers
astro Dev only Runnable environment for the Astro dev process itself
prerender Build Static page rendering during the production build

These are defined in packages/astro/src/core/constants.ts alongside ASTRO_VERSION, redirect status codes, middleware symbols, and Vite environment name constants.

Note

The astro Vite environment is a development-only concept. Production builds only use ssr, client, and prerender. Tooling that introspects Vite environments should handle the absence of the astro environment in production builds gracefully.

1.4 Monorepo Structure

The repository is a pnpm workspace managed by Turborepo:

withastro/astro/
├── packages/
│   ├── astro/                  # Core framework
│   │   ├── src/
│   │   │   ├── cli/            # CLI commands (yargs-parser dispatch)
│   │   │   ├── core/           # Pipeline, config, errors, routing
│   │   │   ├── actions/        # Server actions runtime (defineAction)
│   │   │   ├── assets/         # Image optimization, fonts, SVG (50K+ chars)
│   │   │   ├── config/         # Config loading and resolution
│   │   │   ├── env/            # astro:env module
│   │   │   ├── i18n/           # Internationalization
│   │   │   ├── runtime/        # Client/server runtime, dev toolbar
│   │   │   └── types/          # Public TypeScript types
│   │   ├── components/         # Built-in components (Code, Debug)
│   │   └── test/               # Test fixtures (hundreds)
│   ├── integrations/           # Official integrations (node, vercel, cloudflare, etc.)
│   ├── language-tools/         # VS Code extension, LSP, TS plugin, astro-check
│   ├── create-astro/           # Project scaffolding CLI
│   ├── astro-rss/              # RSS feed generation
│   ├── astro-prism/            # Prism syntax highlighting
│   ├── markdown/               # Markdown processing
│   ├── telemetry/              # Anonymous usage tracking
│   ├── internal-helpers/       # Shared utilities (fs, path, etc.)
│   ├── underscore-redirects/   # _redirects file generation for Netlify/Cloudflare
│   ├── upgrade/                # Version upgrade CLI
│   └── db/                     # Astro DB (CLI + core)
├── examples/                   # Starter templates
├── benchmark/                  # Performance benchmarks
├── scripts/                    # Build/test scripts
└── .changeset/                 # Changeset versioning

1.5 Key Source Modules Reference

Module Path Purpose
CLI Entry packages/astro/src/cli/index.ts Command dispatch (yargs-parser), lazy imports
Config Schema packages/astro/src/core/config/schemas/base.ts Zod v4 schema, ASTRO_CONFIG_DEFAULTS
Base Pipeline packages/astro/src/core/base-pipeline.ts Abstract Pipeline class — middleware, actions, sessions, cache, server islands, routing
App Pipeline packages/astro/src/core/app/pipeline.ts Production pipeline (AppPipeline extends Pipeline)
App packages/astro/src/core/app/app.ts App extends BaseApp — production request handler
NodeApp packages/astro/src/core/app/node.ts NodeApp extends App — Node.js adapter helpers
RenderContext packages/astro/src/core/render-context.ts Per-request rendering context
Middleware packages/astro/src/core/middleware/ sequence(), noop middleware, handler types
Errors packages/astro/src/core/errors/ All error classes
Error Overlay packages/astro/src/core/errors/overlay.ts Dev error overlay (shadow DOM, dark/light theme)
Constants packages/astro/src/core/constants.ts ASTRO_VERSION, redirect codes, middleware symbols
Vite Setup packages/astro/src/core/create-vite.ts Vite config creation
Actions Runtime packages/astro/src/actions/runtime/server.ts defineAction(), ActionError, ActionInputError
Image Utils packages/astro/src/assets/utils/ 17 files — SVG handling, image transforms, responsive images
Font System packages/astro/src/assets/fonts/ Font optimization, format detection, CSS generation
Events/Telemetry packages/astro/src/events/ Telemetry event tracking
Telemetry packages/telemetry/src/ AstroTelemetry class, GlobalConfig for persistent settings
Language Server packages/language-tools/language-server/src/ LSP for .astro files
Astro Check packages/language-tools/astro-check/src/ CLI diagnostics tool
TS Plugin packages/language-tools/ts-plugin/src/ TypeScript language service plugin
VS Code Extension packages/language-tools/vscode/src/ VS Code extension entry
RSS packages/astro-rss/src/ RSS feed generation
Prism packages/astro-prism/src/ Prism syntax highlighting
Underscore Redirects packages/underscore-redirects/src/ _redirects file generation for Netlify/Cloudflare
Internal Helpers packages/internal-helpers/src/ 6 files — shared utilities (fs, path, etc.)
Create Astro packages/create-astro/src/ Project scaffolding wizard

1.6 Islands Architecture

The Islands Architecture is the conceptual core of Astro. Each page renders as static HTML by default; interactive UI components are explicit "islands" that get hydrated on the client. Hydration is controlled via client:* directives (client:load, client:idle, client:visible, client:media, client:only). This model means:

  • The baseline is zero JavaScript delivered to the browser
  • Each island is independently hydrated
  • Server-rendered HTML is complete before any JS loads
  • Multiple UI framework renderers can coexist on a single page

Tip

Islands Architecture is most impactful on content-heavy sites. For highly interactive applications, the zero-JS-by-default model still applies, but islands may cover most of the page. Evaluate whether Astro's model fits the application's interactivity profile before committing.

1.7 Middleware and Actions Architecture

Middleware in Astro is composed via the sequence() utility, which chains middleware functions in order. Each middleware receives the request context and a next function. The middleware chain is resolved by RenderContext per request.

Server Actions, defined with defineAction() in packages/astro/src/actions/runtime/server.ts, provide a type-safe RPC layer callable from client components. Actions can throw ActionError (general) or ActionInputError (validation failure). The action body size is limited by security.actionBodySizeLimit (default 1MB).


2. System Requirements

2.1 Runtime Requirements

Component Minimum Version Notes
Node.js 22.12.0 Enforced at runtime; earlier versions are unsupported
pnpm 10.30.3 Required for monorepo development; enforced via preinstall hook and only-allow
TypeScript ~5.9.3 Bundled; projects may use any compatible version

Warning

The Node.js minimum is 22.12.0. This is enforced in the monorepo build tooling. Adapter-deployed serverless environments must also meet this requirement — Vercel, Netlify, and Cloudflare Workers all support Node.js 22, but verify the specific runtime version in your platform's settings before deploying.

2.2 Development Tooling

Tool Purpose
Turborepo (turbo) Monorepo task orchestration and caching
Vitest Unit and integration testing
Playwright End-to-end testing (Firefox)
Biome Linting and formatting (primary)
ESLint Secondary linting
Prettier Secondary formatting
Changesets Versioning and changelog management
esbuild Package bundling
astro-scripts Internal build scripts
knip Dead code detection

2.3 Optional Runtime Dependencies

Feature Dependency Notes
Image optimization sharp Default image service; required for <Image> transforms in SSR/SSG
MDX support @astrojs/mdx Official integration
Markdoc support @astrojs/markdoc Official integration
SVGO optimization Configured via experimental.svgo Only when flag enabled

3. Configuration Reference

3.1 Configuration File

Astro loads configuration from astro.config.mjs (or .ts, .js, .cjs) at the project root. The schema is defined as a Zod v4 schema in packages/astro/src/core/config/schemas/base.ts with explicit defaults tracked in ASTRO_CONFIG_DEFAULTS.

A minimal configuration:

// astro.config.mjs
import { defineConfig } from 'astro/config';

export default defineConfig({
  site: 'https://example.com',
  output: 'static',
});

A server-rendered configuration with adapter:

// astro.config.mjs
import { defineConfig } from 'astro/config';
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
});

3.2 Top-Level Options

Option Type Default Description
root string '.' Project root directory
srcDir string './src' Source directory
publicDir string './public' Static assets directory
outDir string './dist' Build output directory
cacheDir string './node_modules/.astro' Cache directory
site string (URL) — Fully-qualified deployed site URL; used for canonical URLs and sitemaps
base string '/' Base path when deploying to a subdirectory
trailingSlash 'always' | 'never' | 'ignore' 'ignore' Trailing slash enforcement on routes
output 'static' | 'server' 'static' Output mode; 'hybrid' was removed
compressHTML boolean true Minify HTML output during build
scopedStyleStrategy 'where' | 'class' | 'attribute' 'attribute' Strategy for scoping component styles
adapter object — SSR adapter (required when output: 'server')
integrations array [] Integration list
vite object {} Vite configuration overrides
redirects Record<string, string | {status, destination}> {} URL redirect rules
prerenderConflictBehavior 'error' | 'warn' | 'ignore' 'warn' Behavior when prerendering conflicts are detected

3.3 Build Options (build.*)

Option Type Default Description
build.format 'file' | 'directory' | 'preserve' 'directory' Output file organization format
build.client string './client/' Client-side assets output directory
build.server string './server/' Server-side output directory
build.assets string '_astro' Sub-directory for generated asset files
build.assetsPrefix string | {fallback: string, ...} — CDN prefix for asset URLs
build.serverEntry string 'entry.mjs' Server entry point filename
build.redirects boolean true Generate redirect files during build
build.inlineStylesheets 'always' | 'auto' | 'never' 'auto' Control stylesheet inlining
build.concurrency number (≥1) 1 Number of pages to build concurrently

Tip

Increasing build.concurrency can significantly reduce build time for large sites. Start with 4 and adjust based on available CPU cores. High values may cause memory pressure on resource-constrained build machines.

3.4 Server Options (server.*)

Option Type Default Description
server.host string | boolean false Dev server host binding; true binds to 0.0.0.0
server.port number 4321 Dev server port
server.open string | boolean false Open browser on dev server start
server.headers OutgoingHttpHeaders — Custom HTTP headers served by dev server
server.allowedHosts string[] | true [] Hostnames allowed to access the dev server

3.5 Image Options (image.*)

Option Type Default Description
image.service.entrypoint string 'astro/assets/services/sharp' Image optimization service module
image.service.config Record {} Image service configuration
image.endpoint.route string '/_image' Route for the image optimization endpoint
image.endpoint.entrypoint string — Custom image endpoint module
image.domains string[] [] Allowed external image domains
image.remotePatterns array [] Allowed remote image URL patterns
image.layout 'constrained' | 'fixed' | 'full-width' | 'none' — Default image layout
image.objectFit string — Default CSS object-fit for images
image.objectPosition string — Default CSS object-position for images
image.breakpoints number[] — Responsive image breakpoints
image.responsiveStyles boolean false Auto-inject responsive CSS styles

Remote image patterns support these fields:

// astro.config.mjs
export default defineConfig({
  image: {
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.example.com',
        port: '',
        pathname: '/images/**',
      },
    ],
  },
});

Caution

Allowing overly broad remote patterns (e.g., hostname: '**') effectively disables remote image restrictions. Always scope remotePatterns to the domains you control or trust. Unrestricted patterns allow arbitrary third-party images to be proxied and processed by your image service.

3.6 Markdown Options (markdown.*)

Option Type Default Description
markdown.syntaxHighlight {type: 'shiki'|'prism', excludeLangs?} | false {type: 'shiki'} Syntax highlighting engine
markdown.shikiConfig.theme string (bundled default) Shiki theme name
markdown.shikiConfig.themes Record {} Multiple themes (light/dark)
markdown.shikiConfig.langs array [] Additional Shiki language grammars
markdown.shikiConfig.langAlias Record {} Language name aliases
markdown.shikiConfig.wrap boolean | null — Code block line wrapping
markdown.shikiConfig.transformers array [] Shiki transformer plugins
markdown.shikiConfig.defaultColor 'light' | 'dark' | string | false — Default color scheme for dual-theme mode
markdown.remarkPlugins array [] Remark plugin list
markdown.rehypePlugins array [] Rehype plugin list
markdown.remarkRehype object (defaults) Options passed to remark-rehype
markdown.gfm boolean true GitHub Flavored Markdown support
markdown.smartypants boolean | object (defaults) Smart typography (quotes, dashes)

3.7 Security Options (security.*)

Option Type Default Description
security.checkOrigin boolean true Validate Origin header on form submissions and actions (CSRF protection)
security.allowedDomains array of {hostname?, protocol?, port?} [] Domains permitted beyond same-origin
security.actionBodySizeLimit number 1048576 (1MB) Maximum request body size for server actions
security.serverIslandBodySizeLimit number 1048576 (1MB) Maximum request body size for server islands
security.csp boolean | {algorithm, directives?, styleDirective?, scriptDirective?} false Content Security Policy configuration

3.8 Internationalization Options (i18n)

The i18n block is optional. When present, defaultLocale and locales are required.

Option Type Description
i18n.defaultLocale string Default locale code (e.g., 'en')
i18n.locales array of string | {path, codes} Supported locales
i18n.domains Record<string, URL> Per-locale domain mapping
i18n.fallback Record<string, string> Fallback locale chain
i18n.routing 'manual' | {prefixDefaultLocale?, redirectToDefaultLocale?, fallbackType?} Routing strategy
// astro.config.mjs — multilingual site example
export default defineConfig({
  i18n: {
    defaultLocale: 'en',
    locales: ['en', 'fr', { path: 'pt', codes: ['pt', 'pt-BR'] }],
    routing: {
      prefixDefaultLocale: false,
      redirectToDefaultLocale: true,
    },
    fallback: {
      fr: 'en',
    },
  },
});

3.9 Environment Variable Schema (env.*)

Option Type Default Description
env.schema object {} Type-safe environment variable declarations
env.validateSecrets boolean false Validate secret env vars at build time

3.10 Prefetch Options (prefetch)

Option Type Description
prefetch boolean | {prefetchAll?, defaultStrategy?} Enable prefetching; true enables with defaults
prefetch.defaultStrategy 'tap' | 'hover' | 'viewport' | 'load' When to prefetch links

3.11 Dev Toolbar Options (devToolbar.*)

Option Type Default Description
devToolbar.enabled boolean true Show the dev toolbar during development
devToolbar.placement 'bottom-left' | 'bottom-center' | 'bottom-right' — Toolbar screen position

3.12 Font Options (fonts)

The fonts option accepts an array of FontFamilySchema objects for built-in font optimization. This connects to the font system in packages/astro/src/assets/fonts/, which handles format detection, CSS generation, and serving optimized font files.

3.13 Session Options (session)

The optional session block configures server-side session storage using a driver-based architecture. When using the Node.js adapter with no driver configured, filesystem sessions are auto-enabled.

3.14 Legacy Options (legacy.*)

Option Type Default Description
legacy.collectionsBackwardsCompat boolean false Enable backwards-compatible content collections behavior

3.15 Experimental Options (experimental.*)

These flags are subject to change or removal. Do not rely on them in production without evaluating stability.

Option Type Default Description
experimental.clientPrerender boolean false Enable Speculation Rules API for client-side prerendering
experimental.contentIntellisense boolean false Enhanced content collection IntelliSense in VS Code
experimental.chromeDevtoolsWorkspace boolean false Chrome DevTools workspace integration
experimental.svgo boolean | SvgoConfig false SVGO optimization for SVG assets
experimental.cache CacheSchema — Response caching configuration
experimental.routeRules RouteRulesSchema — Per-route configuration rules
experimental.rustCompiler boolean false Use the Rust-based Astro compiler
experimental.queuedRendering {enabled?, poolSize?, contentCache?} {enabled: false} Queued rendering via NodePool

Note

experimental.queuedRendering uses the NodePool class to manage concurrent rendering workers. The poolSize option controls parallelism. contentCache enables the HTMLStringCache for caching rendered HTML strings between requests.


4. Deployment & Scaling

4.1 Deployment Modes

Astro supports two fundamental output modes:

Mode Config Use Case
static output: 'static' Pre-rendered HTML; host anywhere (CDN, object storage, static host)
server output: 'server' + adapter On-demand SSR; requires a runtime environment

Static output produces a complete dist/ directory deployable to any CDN or static host without server infrastructure.

Server output requires an adapter that produces a deployable artifact for the target platform.

4.2 Node.js Adapter (@astrojs/node)

The Node.js adapter supports two modes, and the mode option is required — omitting it throws an AstroError.

// astro.config.mjs — standalone mode
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'standalone' }),
});
// astro.config.mjs — middleware mode (Express/Fastify compatible)
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({ mode: 'middleware' }),
});

Standalone mode: Includes a built-in HTTP server. Run the output with node ./dist/server/entry.mjs.

Middleware mode: Exports an Express/Fastify-compatible middleware function. Integrate it into an existing Node.js server.

Node Adapter Options

Option Type Default Description
mode 'standalone' | 'middleware' Required Deployment mode
bodySizeLimit number 1GB Maximum request body size
staticHeaders object — HTTP headers injected for static file responses
experimentalDisableStreaming boolean — Disable response streaming

Node Adapter Environment Variables

Variable Purpose
ASTRO_NODE_AUTOSTART Auto-start the server in standalone mode
ASTRO_NODE_LOGGING Control logging verbosity
HOST Override the server host
PORT Override the server port
SERVER_CERT_PATH Path to TLS certificate for HTTPS
SERVER_KEY_PATH Path to TLS private key for HTTPS

HTTPS is enabled automatically when both SERVER_CERT_PATH and SERVER_KEY_PATH are set.

4.3 Vercel Adapter (@astrojs/vercel)

The Vercel adapter deploys to Vercel's serverless or edge runtime.

// astro.config.mjs
import vercel from '@astrojs/vercel';

export default defineConfig({
  output: 'server',
  adapter: vercel(),
});

Key capabilities:

  • ISR (Incremental Static Regeneration): Combine static generation with on-demand revalidation
  • Skew Protection: When VERCEL_SKEW_PROTECTION_ENABLED is set, the adapter syncs deployment identifiers
  • maxDuration: Configure maximum function execution time (must be a positive number)
  • VercelBuilder class handles the build configuration and output format expected by Vercel's build system

Vercel Environment Variables

Variable Purpose
VERCEL_DEPLOYMENT_ID Vercel deployment identifier (auto-set by Vercel)
VERCEL_SKEW_PROTECTION_ENABLED Enable deployment skew protection (auto-set by Vercel)

4.4 Cloudflare Adapter (@astrojs/cloudflare)

The Cloudflare adapter targets Cloudflare Workers and Cloudflare Pages.

// astro.config.mjs
import cloudflare from '@astrojs/cloudflare';

export default defineConfig({
  output: 'server',
  adapter: cloudflare(),
});

Key capabilities:

  • Cloudflare Workers and Pages deployment
  • Durable Objects support
  • Custom entry file configuration
  • Image service options for Cloudflare Images

Cloudflare Environment Variables

Variable Purpose
CLOUDFLARE_VITE_BUILD Signal that a Cloudflare Vite build is occurring

Warning

Cloudflare Workers have runtime constraints that differ from Node.js. The nodejs_compat compatibility flag must be enabled in your Cloudflare configuration when using Node.js-compatible APIs. A known issue (#16291) affects CSS nesting in the Cloudflare dev server — test in production preview environments when CSS nesting is used.

4.5 Netlify Adapter (@astrojs/netlify)

// astro.config.mjs
import netlify from '@astrojs/netlify';

export default defineConfig({
  output: 'server',
  adapter: netlify(),
});

Key capabilities:

  • Automatic _redirects file generation via packages/underscore-redirects/
  • Netlify Functions deployment

Known limitations:

  • context.rewrite() is not available in the Netlify adapter
  • Astro.url and Astro.cookies have compatibility considerations in certain contexts

Netlify Environment Variables

Variable Purpose
DEPLOY_ID Netlify deploy identifier (auto-set by Netlify)
NETLIFY Netlify environment detection flag
NETLIFY_LOCAL Local Netlify dev detection
NETLIFY_DEV Netlify dev server detection

4.6 Static Deployment

For output: 'static', the build output in outDir (default ./dist) is a complete set of static files deployable to any host:

# Build for static deployment
astro build

# dist/ can be deployed to:
# - GitHub Pages
# - Netlify (static)
# - Vercel (static)
# - Cloudflare Pages (static)
# - S3 + CloudFront
# - Any nginx/Apache host

Use build.assetsPrefix to point asset URLs at a CDN:

export default defineConfig({
  build: {
    assetsPrefix: 'https://cdn.example.com',
  },
});

4.7 Concurrency and Scaling

For high-traffic SSR deployments, horizontal scaling at the load balancer level is the primary mechanism. The adapter handles individual requests; Astro itself does not manage process pools in standard deployments.

For build-time scaling, build.concurrency controls parallel page rendering. The experimental.queuedRendering feature provides a NodePool-based worker pool for controlled concurrency within a single process, with poolSize setting the pool size and contentCache enabling HTMLStringCache for repeated content.


5. Operations

5.1 Environment Variables Reference

Variable Source Module Purpose
ASTRO_TIMER_PATH core/config/timer.ts Timer output path for build profiling
ASTRO_NODE_AUTOSTART node/preview.ts Auto-start Node adapter server
ASTRO_NODE_LOGGING node/standalone.ts Node adapter logging control
HOST node/preview.ts Node adapter server host override
PORT node/standalone.ts Node adapter server port override
SERVER_CERT_PATH node/standalone.ts HTTPS certificate file path
SERVER_KEY_PATH node/standalone.ts HTTPS private key file path
VERCEL_DEPLOYMENT_ID vercel/index.ts Vercel deployment ID
VERCEL_SKEW_PROTECTION_ENABLED vercel/index.ts Vercel skew protection activation
DEPLOY_ID netlify/index.ts Netlify deploy ID
NETLIFY netlify/index.ts Netlify environment detection
NETLIFY_LOCAL netlify/index.ts Local Netlify dev detection
NETLIFY_DEV netlify/index.ts Netlify dev server detection
CLOUDFLARE_VITE_BUILD cloudflare/index.ts Cloudflare build flag
NODE_ENV various Runtime environment (development/production)
CI scripts/cmd/test.js CI environment detection

5.2 Monitoring and Health

Astro does not include built-in health check endpoints. For SSR deployments, implement health checks at the adapter layer:

  • Node standalone: Add a health check route to your server configuration
  • Vercel/Netlify/Cloudflare: Use platform-native health monitoring
  • All platforms: Monitor the / route or a dedicated /health endpoint added to your Astro project

5.3 Telemetry

Astro collects anonymous usage telemetry via packages/telemetry/. The AstroTelemetry class sends anonymized events about command usage, configuration choices, and build outcomes. Persistent telemetry preferences are stored by GlobalConfig.

Telemetry can be disabled:

# Disable telemetry
astro telemetry disable

# Enable telemetry
astro telemetry enable

# Check telemetry status
astro telemetry status

No personally identifiable information is collected. The telemetry system tracks aggregate patterns to inform framework development priorities.

5.4 Dev Error Overlay

During development, errors surface through the dev error overlay defined in packages/astro/src/core/errors/overlay.ts. The overlay renders in a shadow DOM to prevent style conflicts and supports both dark and light themes. It displays:

  • Error class and message
  • Stack trace with source file links
  • Hint for known error patterns

Errors shown in the overlay correspond to the error class hierarchy — AstroError, CompilerError, CSSError, MarkdownError, InternalError, AggregateError — with user-facing errors (AstroUserError) rendered with actionable messaging.

5.5 Cache Directory

Astro uses ./node_modules/.astro as its default cache directory (cacheDir). This cache stores compiled component artifacts, type generation outputs, and build intermediates.

To clear the cache:

rm -rf ./node_modules/.astro

Note

CI environments should cache ./node_modules/.astro between runs to avoid redundant compilation. Include the cache key in your CI hash along with pnpm-lock.yaml and astro.config.* to invalidate appropriately when config changes.

5.6 Logging

Astro's logging is managed per-command and surfaces to stdout/stderr. The ASTRO_NODE_LOGGING environment variable controls log verbosity for the Node adapter. Production deployments should configure platform-native log aggregation (e.g., Vercel Log Drains, Netlify Log Streams, Cloudflare Workers Logpush).


6. Performance

6.1 Build Performance

Increase build concurrency:

// astro.config.mjs
export default defineConfig({
  build: {
    concurrency: 4, // parallelize page rendering
  },
});

Inline stylesheets aggressively:

export default defineConfig({
  build: {
    inlineStylesheets: 'always', // eliminates render-blocking CSS requests
  },
});

Use CDN for assets:

export default defineConfig({
  build: {
    assetsPrefix: 'https://cdn.example.com',
  },
});

Cache the Astro cache directory in CI with a key based on pnpm-lock.yaml + astro.config.*.

6.2 Image Performance

The sharp-based image service (astro/assets/services/sharp) is the default and provides the best throughput. Configuration options in image.service.config are passed directly to sharp.

Responsive images via image.responsiveStyles: true auto-inject CSS for responsive layouts. Define image.breakpoints to control the set of generated sizes:

export default defineConfig({
  image: {
    breakpoints: [320, 640, 768, 1024, 1280, 1920],
    responsiveStyles: true,
    layout: 'constrained',
  },
});

For SSR deployments, image transforms are computed on-demand at /_image (configurable via image.endpoint.route). High-traffic deployments should place a CDN in front of this endpoint and cache transformed images by URL.

6.3 JavaScript Bundle Performance

Astro's Islands Architecture inherently minimizes client JavaScript. Additional practices:

  • Use client:visible instead of client:load for below-the-fold islands — they hydrate only when entering the viewport
  • Use client:idle for non-critical islands to defer hydration until the main thread is idle
  • Use client:only only when server rendering is impossible (third-party widgets, browser-only APIs)
  • Prefer static components for content-only sections

6.4 HTML Performance

HTML compression is on by default (compressHTML: true). The HTML minification reduces whitespace in the rendered output. For content-heavy sites with large HTML payloads, this yields measurable transfer size reductions.

build.inlineStylesheets: 'auto' (the default) inlines small stylesheets and externalizes large ones. Tune with 'always' or 'never' based on profiling.

6.5 Prefetching

Prefetching reduces perceived navigation latency for multi-page sites:

export default defineConfig({
  prefetch: {
    prefetchAll: true,        // prefetch all internal links
    defaultStrategy: 'hover', // prefetch on hover
  },
});

Strategy options and their behavior:

Strategy Trigger
tap Prefetch on pointer down (minimal delay)
hover Prefetch when hovering over a link
viewport Prefetch links as they enter the viewport
load Prefetch all eligible links on page load

Tip

'viewport' strategy is ideal for paginated content or listicles where the next page link is visible before the user clicks. 'hover' balances bandwidth with responsiveness for most content sites.

6.6 Queued Rendering (Experimental)

export default defineConfig({
  experimental: {
    queuedRendering: {
      enabled: true,
      poolSize: 4,
      contentCache: true,
    },
  },
});

When enabled, server-side rendering is handled by a NodePool of workers. contentCache: true activates HTMLStringCache to cache rendered HTML strings for repeated identical requests. This is a significant architectural change — evaluate with load testing before enabling in production.

6.7 Build Profiling

Set ASTRO_TIMER_PATH to a file path to capture build timing data:

ASTRO_TIMER_PATH=./build-timings.json astro build

The timer output can identify slow routes, modules, or integrations contributing to build time.


7. Security

7.1 CSRF Protection

Origin checking is enabled by default via security.checkOrigin: true. This validates the Origin request header on form submissions and server action calls, preventing cross-site request forgery. The validation is handled in the middleware chain during request processing.

To allow cross-origin requests from trusted domains:

export default defineConfig({
  security: {
    checkOrigin: true,
    allowedDomains: [
      { hostname: 'trusted-partner.com', protocol: 'https' },
    ],
  },
});

Important

Never set security.checkOrigin: false in production SSR deployments unless you have an alternative CSRF mitigation. The origin check is a primary defense for server actions and form handlers against cross-site forgery attacks.

7.2 Content Security Policy

CSP is supported natively via security.csp:

export default defineConfig({
  security: {
    csp: {
      algorithm: 'sha256',
      directives: {
        'default-src': ["'self'"],
        'img-src': ["'self'", 'data:', 'https:'],
      },
      scriptDirective: {
        // Hashes are auto-generated for inline scripts
      },
      styleDirective: {
        // Hashes are auto-generated for inline styles
      },
    },
  },
});

When CSP is configured with algorithm, Astro automatically generates content hashes for inline scripts and styles, eliminating the need for 'unsafe-inline' in most cases.

7.3 Body Size Limits

Two separate body size limits protect against large payload attacks:

export default defineConfig({
  security: {
    actionBodySizeLimit: 1048576,       // 1MB — server actions
    serverIslandBodySizeLimit: 1048576, // 1MB — server islands
  },
});

The Node adapter has a separate bodySizeLimit option (default 1GB) at the HTTP layer, applied before Astro's routing. When BodySizeLimitError is thrown (from NodeApp), it surfaces as a 413 Payload Too Large response.

7.4 HTTPS in Node Adapter

Configure HTTPS via environment variables:

export SERVER_CERT_PATH=/path/to/cert.pem
export SERVER_KEY_PATH=/path/to/key.pem
node ./dist/server/entry.mjs

When both variables are set, the standalone Node server binds to HTTPS automatically.

7.5 Static File Headers

The Node adapter's staticHeaders option injects HTTP headers for static file responses. Use this to add security headers to static assets without a reverse proxy:

import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  adapter: node({
    mode: 'standalone',
    staticHeaders: {
      'X-Content-Type-Options': 'nosniff',
      'X-Frame-Options': 'DENY',
    },
  }),
});

7.6 Remote Image Security

Untrusted remote images processed by the image optimization service represent an SSRF risk. Restrict allowed origins:

export default defineConfig({
  image: {
    domains: ['images.example.com'],
    remotePatterns: [
      {
        protocol: 'https',
        hostname: '**.trusted-cdn.com',
      },
    ],
  },
});

Any image URL not matching domains or remotePatterns is rejected by the image endpoint.

7.7 Server Island Security

Server islands — dynamic components rendered server-side within otherwise static pages — accept POST requests with component state. The security.serverIslandBodySizeLimit cap prevents oversized payloads. The origin check (security.checkOrigin) applies to server island requests.

7.8 Actions Security

Server actions defined with defineAction() are accessible via POST requests. Security layers:

  • Origin validation (when security.checkOrigin: true)
  • Body size capped at security.actionBodySizeLimit
  • Input validation via Zod schemas (throws ActionInputError on schema violations)
  • Error handling via ActionError with explicit HTTP status codes

Caution

Actions that accept file uploads or large payloads should explicitly set security.actionBodySizeLimit above the default 1MB. For public-facing forms, implement rate limiting at the CDN or reverse proxy layer — Astro does not include built-in rate limiting.


8. Developer Internals

8.1 Error Class Reference

All error classes are defined in packages/astro/src/core/errors/errors.ts and share a common root through AstroError:

Class Extends Use Case
AstroError Error Base for all framework errors; carries error code, hint, location
CompilerError AstroError Errors from the Astro compiler (.astro file parsing)
CSSError AstroError CSS processing failures (PostCSS, scoping, nesting)
MarkdownError AstroError Markdown/MDX processing failures
InternalError AstroError Internal framework errors; always indicates a framework bug
AggregateError AstroError Multiple simultaneous errors (e.g., batch build failures)
AstroUserError Error User-facing errors with actionable messaging (separate hierarchy)
MarkdocError Error Errors from the Markdoc integration
BodySizeLimitError Error Request body exceeded the configured size limit

InternalError should never be thrown in normal operation — encountering one indicates a framework bug that should be reported to the withastro/astro issue tracker.

8.2 Pipeline Internals

The Pipeline abstract class in packages/astro/src/core/base-pipeline.ts defines the contract for all request handling. Key responsibilities:

  • Composing the middleware chain via sequence()
  • Resolving server actions
  • Managing session initialization and teardown
  • Cache provider coordination
  • Server island request routing
  • File-based route resolution

AppPipeline (production) implements this contract for serving requests from the built artifact. During development, an equivalent dev pipeline operates against the Vite dev server's module graph.

RenderContext (packages/astro/src/core/render-context.ts) is instantiated per request and carries:

  • The incoming request object
  • Resolved route parameters
  • Middleware-modified locals
  • Session reference
  • Action result state

8.3 Config Loading

Configuration loading happens in two phases:

  1. File discovery: Astro looks for astro.config.mjs, astro.config.ts, astro.config.js, astro.config.cjs at the project root
  2. Schema validation: The loaded config is validated against the Zod v4 schema in packages/astro/src/core/config/schemas/base.ts; unknown keys emit warnings, invalid values throw AstroUserError

ASTRO_CONFIG_DEFAULTS in the schema module defines all defaults, making the effective configuration always fully resolved with no partial states.

8.4 CLI Architecture

The CLI entry point at packages/astro/src/cli/index.ts uses yargs-parser for argument parsing with lazy imports for each subcommand. Lazy imports ensure the CLI starts fast — heavy dependencies (Vite, compiler) are only loaded when their command is actually invoked.

Commands are dispatched by subcommand name. Each command module is independently imported on demand.

8.5 Asset and Image Pipeline

The image pipeline in packages/astro/src/assets/utils/ (17 files) handles:

  • SVG passthrough and optional SVGO optimization
  • Image format detection and conversion
  • Responsive image srcset generation
  • Remote image URL validation against configured patterns
  • Sharp-based image transforms (resize, format conversion, quality)

The font system in packages/astro/src/assets/fonts/ manages:

  • Font file format detection
  • @font-face CSS generation
  • Font serving through the dev server and build output
  • Integration with the fonts configuration array

8.6 Writing an Integration

Astro integrations are objects with a name and hooks property. Hooks fire at defined lifecycle points during build and dev:

// my-integration.ts
import type { AstroIntegration } from 'astro';

export function myIntegration(): AstroIntegration {
  return {
    name: 'my-integration',
    hooks: {
      'astro:config:setup': ({ config, updateConfig, addRenderer, injectRoute }) => {
        // Modify config, add routes, add renderers
        updateConfig({
          vite: {
            plugins: [myVitePlugin()],
          },
        });
      },
      'astro:config:done': ({ config }) => {
        // Read the final resolved config
      },
      'astro:server:setup': ({ server }) => {
        // Access the Vite dev server
      },
      'astro:build:start': () => {
        // Before the build starts
      },
      'astro:build:done': ({ dir, routes, pages }) => {
        // After the build completes
      },
    },
  };
}

Note

Integration hooks run in the order integrations are listed in integrations: []. When multiple integrations modify the same config value via updateConfig, the last write wins. Design integrations to be composable and avoid assuming exclusive ownership of any config key.

8.7 Writing a Renderer Integration

UI framework renderers (React, Vue, Svelte, Preact, Solid) are a specialized form of integration that add addRenderer() calls in the astro:config:setup hook:

'astro:config:setup': ({ addRenderer }) => {
  addRenderer({
    name: 'my-framework',
    serverEntrypoint: 'my-framework/server',  // SSR render function
    clientEntrypoint: 'my-framework/client',  // Client hydration
  });
},

The renderer's server entrypoint exports a render function; the client entrypoint exports a hydrate function. These are called by Astro's component runtime during SSR and client hydration respectively.

8.8 Official Integrations Reference

Integration Package Source Purpose
Node adapter @astrojs/node node/src/ (11 files) Node.js standalone and middleware deployment
Cloudflare adapter @astrojs/cloudflare cloudflare/src/ (7 files + 9 utils) Cloudflare Workers/Pages deployment
Vercel adapter @astrojs/vercel vercel/src/ (3 files + 4 lib) Vercel serverless/edge deployment
Netlify adapter @astrojs/netlify netlify/src/ (6 files + 1 lib) Netlify deployment
React @astrojs/react react/src/ (12 files) React 18 & 19 renderer
Vue @astrojs/vue vue/src/ (6 files) Vue 3 renderer
Svelte @astrojs/svelte svelte/src/ (6 files) Svelte 5 renderer
Preact @astrojs/preact preact/src/ (8 files) Preact renderer
Solid.js @astrojs/solid-js solid/src/ Solid.js renderer
Alpine.js @astrojs/alpinejs alpinejs/src/ (1 file) Alpine.js integration
MDX @astrojs/mdx mdx/src/ (11 files) MDX (Markdown + JSX) support
Markdoc @astrojs/markdoc markdoc/src/ (10 files) Markdoc authoring format support
Sitemap @astrojs/sitemap sitemap/src/ (7 files) XML sitemap generation
Partytown @astrojs/partytown partytown/src/ (2 files) Third-party script offloading to Web Workers

8.9 Telemetry Internals

AstroTelemetry in packages/telemetry/src/ tracks anonymized events from packages/astro/src/events/. GlobalConfig handles persistent storage of telemetry consent. Events fire for CLI commands, integration usage, and build completion. No source code, configuration values, or file paths are included in telemetry payloads.

8.10 RouteCache

RouteCache caches the results of route matching and resolution. It is populated during the dev server startup and cleared on file changes that affect routing. In production builds, routing is resolved at build time; the route cache is not used at runtime in static deployments.

8.11 Contributing to the Monorepo

Setup:

# Clone the repository
git clone https://github.com/withastro/astro.git
cd astro

# Install dependencies (pnpm required)
pnpm install

# Build all packages
pnpm build

Common development tasks:

# Format code (Biome + Prettier)
pnpm format

# Lint (Biome + knip + ESLint)
pnpm lint

# Run all tests
pnpm test

# Run core package tests only
pnpm test:astro

# Run integration tests
pnpm test:integrations

# Run language tools tests
pnpm test:language-tools

# Run E2E tests (Playwright, Firefox)
pnpm test:e2e

# Run smoke tests for examples
pnpm test:smoke

# Run type checking tests
pnpm test:types

Creating a changeset:

pnpm changeset

Follow the prompts to select affected packages and describe the change. Changesets are consumed during release to generate changelogs and bump version numbers.

Building a release:

pnpm run release

This runs the build pipeline and publishes packages via Changesets.

Note

The monorepo enforces pnpm 10.30.3 via a preinstall hook using only-allow. Running npm install or yarn install will fail with an error instructing you to use pnpm. This enforcement is intentional to ensure lockfile consistency across all contributors.


9. Integration Points

9.1 Language Tooling

Astro provides first-class language tooling for .astro files through packages/language-tools/:

Component Package Description
Language Server @astrojs/language-server LSP implementation for .astro files — powers all editor integrations
VS Code Extension astro-vscode VS Code extension using the language server
TypeScript Plugin @astrojs/ts-plugin TypeScript language service plugin for .astro imports in .ts files
Astro Check @astrojs/check CLI diagnostics tool for type checking .astro files

Using astro-check in CI:

# Install
npm install --save-dev @astrojs/check typescript

# Run type checking
astro check

astro-check exits non-zero on type errors, making it suitable for CI pipelines. It uses the language server's diagnostic engine to type-check .astro component scripts, props, and expressions.

Note

The tsconfck library used by the language tooling has been discontinued (tracked in issue #16385). Monitor upstream developments for migration guidance. If you encounter errors related to tsconfig resolution in the language server, check for updates to @astrojs/language-server.

9.2 Vite Plugin Integration

Astro wraps Vite and exposes the Vite configuration via vite: {} in astro.config. Integrations can add Vite plugins via updateConfig() in the astro:config:setup hook.

Vite plugin caveats in Astro:

  • Plugins run in multiple Vite environments (ssr, client, prerender). Use enforce and apply options appropriately
  • The astro Vite environment is dev-only; plugins must handle its absence in production
  • Avoid plugins that rely on vite.config.js — Astro generates its Vite config dynamically via packages/astro/src/core/create-vite.ts

9.3 RSS Feed Generation

@astrojs/rss in packages/astro-rss/ provides a utility for generating RSS feeds from Astro endpoints:

// src/pages/rss.xml.ts
import rss from '@astrojs/rss';
import { getCollection } from 'astro:content';

export async function GET(context) {
  const posts = await getCollection('blog');
  return rss({
    title: 'My Blog',
    description: 'My blog description',
    site: context.site,
    items: posts.map((post) => ({
      title: post.data.title,
      pubDate: post.data.date,
      link: `/blog/${post.slug}/`,
    })),
  });
}

9.4 Sitemap Generation

@astrojs/sitemap in packages/integrations/sitemap/ generates sitemap-index.xml and per-page sitemaps during build:

import sitemap from '@astrojs/sitemap';

export default defineConfig({
  site: 'https://example.com',
  integrations: [sitemap()],
});

The site option is required for sitemap generation — without it, the integration cannot construct absolute URLs.

9.5 Underscore Redirects

packages/underscore-redirects/ generates _redirects files in the Netlify format, which Cloudflare Pages also supports. This package is used internally by the Netlify and Cloudflare adapters to translate Astro's redirects configuration into platform-native redirect rules.

9.6 Partytown Integration

@astrojs/partytown offloads third-party scripts (analytics, tag managers) to Web Workers using the Partytown library. This prevents third-party scripts from blocking the main thread:

import partytown from '@astrojs/partytown';

export default defineConfig({
  integrations: [
    partytown({
      // Forward dataLayer.push calls from the worker to the main thread
      config: { forward: ['dataLayer.push'] },
    }),
  ],
});

9.7 Astro DB

packages/db/ provides Astro DB — a local and cloud-connected SQLite database layer. The DB package includes a substantial CLI (20K+ chars) and core runtime (27K+ chars). It integrates with Astro's content pipeline and provides typed table access.

9.8 Create Astro Scaffolding

packages/create-astro/ provides the project scaffolding wizard invoked via:

npm create astro@latest

The wizard guides through template selection, TypeScript preferences, and dependency installation. Templates are sourced from examples/ in the monorepo.

9.9 Prism Integration

packages/astro-prism/ provides a Prism-based syntax highlighting component. This predates Astro's Shiki integration (now the default). It remains for projects that prefer Prism's smaller bundle footprint or need Prism-specific language grammars.

To use Prism highlighting instead of Shiki:

export default defineConfig({
  markdown: {
    syntaxHighlight: {
      type: 'prism',
      excludeLangs: [],
    },
  },
});

10. Troubleshooting

10.1 output: 'hybrid' Configuration Error

Problem: Build fails with an error about invalid output value.

Cause: The hybrid output mode was removed. Configuration files from earlier Astro versions may still reference it.

Fix: Change output: 'hybrid' to output: 'server' in astro.config.*. All pages prerender by default in server mode; add export const prerender = false to pages that need on-demand rendering.

10.2 Node Adapter Mode Missing

Problem: AstroError thrown during build: mode is required.

Cause: @astrojs/node requires the mode option ('standalone' or 'middleware').

Fix:

adapter: node({ mode: 'standalone' }) // or 'middleware'

10.3 Dev Server Asset Errors (TypeError in assets/internal.js)

Problem: TypeError in assets/internal.js during development (issue #16309).

Cause: Usually caused by a version mismatch between astro and an integration, or a corrupted .astro cache.

Fix:

  1. Clear the cache: rm -rf ./node_modules/.astro
  2. Ensure all @astrojs/* packages are on compatible versions
  3. Restart the dev server

10.4 Vue Scoped Styles Lost After Navigation

Problem: Vue component scoped styles disappear after <ClientRouter> (View Transitions) navigation (issue #16334).

Cause: Known issue with how Vue's scoped style injection interacts with ClientRouter's page replacement.

Fix: Monitor the issue tracker for a patch. As a workaround, use global CSS or CSS Modules for styles that must persist across view transitions.

10.5 Components Not Rendered on Page Refresh in Dev

Problem: Page shows missing components after hard refresh in the dev server (issue #15925).

Cause: Module graph inconsistency in the dev environment.

Fix: Stop and restart the dev server. If the issue recurs, clear ./node_modules/.astro and restart.

10.6 CSS Missing with export const partial = true

Problem: CSS not injected when a page exports partial = true (issue #16296).

Cause: Partial pages bypass the normal HTML shell rendering, which includes CSS injection.

Fix: Manually include the CSS link in the partial's template, or inject styles via a shared stylesheet referenced by the parent page.

10.7 Cloudflare Dev Server CSS Nesting Issue

Problem: CSS nesting syntax causes errors in the Cloudflare adapter's local dev server (issue #16291).

Cause: The Cloudflare Workers runtime's CSS parser in the dev simulator does not support CSS nesting the same way as production.

Fix: Test CSS nesting in a Cloudflare Pages preview deployment rather than local dev. Use PostCSS with the postcss-nesting plugin as a compilation step to flatten nesting before it reaches the runtime.

10.8 UnoCSS @apply Incompatibility

Problem: UnoCSS @apply directives cause build errors or unexpected output (issue #16373).

Cause: Ordering conflict between UnoCSS's processing and Astro's CSS pipeline.

Fix: Configure UnoCSS's Vite plugin to run before Astro's CSS processing by adjusting plugin order in vite.plugins. Alternatively, avoid @apply and use UnoCSS's utility classes directly.

10.9 tsconfck Discontinuation

Problem: Language server errors related to tsconfig.json resolution (issue #16385).

Cause: The tsconfck library used by @astrojs/language-server has been discontinued.

Fix: Upgrade to the latest @astrojs/language-server version. The Astro team is tracking the migration away from tsconfck.

10.10 HTTPS Not Starting in Node Standalone

Problem: Node standalone server starts on HTTP despite setting cert/key paths.

Cause: Both SERVER_CERT_PATH and SERVER_KEY_PATH must be set simultaneously. Setting only one is ignored.

Fix: Verify both environment variables are exported before starting the server:

export SERVER_CERT_PATH=/path/to/cert.pem
export SERVER_KEY_PATH=/path/to/key.pem
node ./dist/server/entry.mjs

10.11 Image Optimization Failing in SSR

Problem: <Image> component throws errors during SSR.

Cause: The sharp package requires native binaries. Platform-specific builds (e.g., building on macOS, deploying to Linux) may have incompatible binaries.

Fix: Run npm rebuild sharp in the deployment environment, or configure the deployment platform to rebuild native modules. Alternatively, use a custom image service with image.service.entrypoint.

10.12 BodySizeLimitError on Large File Uploads

Problem: 413 errors when uploading files via server actions or server islands.

Cause: Default body size limits are 1MB for actions and server islands.

Fix: Increase the limits in security config:

export default defineConfig({
  security: {
    actionBodySizeLimit: 10 * 1024 * 1024, // 10MB
  },
});

For very large files, consider pre-signed upload URLs directly to object storage instead of routing through Astro.

10.13 pnpm Version Mismatch in Monorepo

Problem: pnpm install fails with "This project requires pnpm X.Y.Z".

Cause: The monorepo enforces pnpm 10.30.3 via only-allow.

Fix: Install the correct pnpm version:

npm install -g pnpm@10.30.3

10.14 Build Failing Due to Missing site Config

Problem: Sitemap generation, canonical URLs, or RSS feeds produce incorrect output.

Cause: The site configuration option is not set.

Fix: Add site to astro.config.*:

export default defineConfig({
  site: 'https://your-domain.com',
});

10.15 Prerender Conflicts

Problem: Build warnings or errors about prerender conflicts.

Cause: Two configurations are producing conflicting prerender decisions for the same route.

Fix: Set prerenderConflictBehavior: 'error' during development to catch conflicts early, then resolve by making prerender decisions explicit:

export default defineConfig({
  prerenderConflictBehavior: 'error',
});

Quick Reference

Configuration Defaults Summary

Config Key Default
output 'static'
base '/'
trailingSlash 'ignore'
compressHTML true
scopedStyleStrategy 'attribute'
build.format 'directory'
build.assets '_astro'
build.serverEntry 'entry.mjs'
build.inlineStylesheets 'auto'
build.concurrency 1
server.port 4321
server.host false
image.service.entrypoint 'astro/assets/services/sharp'
image.endpoint.route '/_image'
image.responsiveStyles false
markdown.syntaxHighlight.type 'shiki'
markdown.gfm true
security.checkOrigin true
security.actionBodySizeLimit 1048576 (1MB)
security.serverIslandBodySizeLimit 1048576 (1MB)
security.csp false
devToolbar.enabled true
legacy.collectionsBackwardsCompat false
env.validateSecrets false
experimental.clientPrerender false
experimental.rustCompiler false
experimental.queuedRendering.enabled false

Adapter Compatibility Matrix

Feature Node Vercel Cloudflare Netlify Static
SSR Yes Yes Yes Yes No
Server Actions Yes Yes Yes Yes No
Server Islands Yes Yes Yes Yes No
Sessions (auto) Yes (filesystem) — — — No
ISR — Yes — — —
HTTPS built-in Yes Platform Platform Platform N/A
context.rewrite Yes Yes Yes No N/A

Vite Environments Reference

Environment Build Dev Purpose
ssr Yes Yes Server-side rendering
client Yes No Client bundles
astro No Yes Dev process runtime
prerender Yes No Static page generation