> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/withastro/astro/llms.txt
> Use this file to discover all available pages before exploring further.

# Integrations API

> Learn how to build Astro integrations with the Integrations API

Astro Integrations add new functionality and behaviors for your project with just a few lines of code. This page describes the API for building your own integrations.

## Integration Structure

An Astro integration is an object with a `name` and `hooks` property:

```ts theme={null}
export interface AstroIntegration {
  name: string;
  hooks: IntegrationHooks;
}
```

## Basic Example

```js theme={null}
function myIntegration() {
  return {
    name: 'my-integration',
    hooks: {
      'astro:config:setup': ({ config, command, updateConfig }) => {
        // Run during setup
      },
      'astro:build:done': ({ dir, pages }) => {
        // Run after build
      }
    }
  };
}
```

## Integration Hooks

Integrations can define hook functions that run at specific times during Astro's lifecycle. All hooks are optional.

### `astro:config:setup`

<ParamField path="hooks['astro:config:setup']" type="function">
  Called during Astro initialization, before the Vite or Astro config have been resolved. This hook can be used to extend project configuration.

  **Parameters:**

  * `config` - A read-only copy of the user-supplied Astro config
  * `command` - The command used to run Astro: `'dev'`, `'build'`, `'preview'`, or `'sync'`
  * `isRestart` - Whether the dev server is restarting
  * `updateConfig` - Function to update the user config
  * `addRenderer` - Add a framework renderer (React, Vue, etc.)
  * `addWatchFile` - Add a file to watch for changes
  * `injectScript` - Inject a client script into pages
  * `injectRoute` - Add a new route to the Astro project
  * `addClientDirective` - Add a custom client directive
  * `addDevToolbarApp` - Add a custom dev toolbar app
  * `addMiddleware` - Add middleware
  * `createCodegenDir` - Create a directory for generated code
  * `logger` - Integration logger instance

  ```js theme={null}
  'astro:config:setup': ({ updateConfig, addRenderer, injectScript }) => {
    // Update config
    updateConfig({
      vite: {
        plugins: [myVitePlugin()]
      }
    });

    // Add a framework renderer
    addRenderer({
      name: '@astrojs/react',
      serverEntrypoint: '@astrojs/react/server.js'
    });

    // Inject a script
    injectScript('page', 'console.log("Hello from my integration!");');
  }
  ```
</ParamField>

### `astro:config:done`

<ParamField path="hooks['astro:config:done']" type="function">
  Called after the Astro config has been fully resolved and other integrations have run their `astro:config:setup` hooks.

  **Parameters:**

  * `config` - The resolved Astro config
  * `setAdapter` - Set the adapter for SSR
  * `injectTypes` - Inject TypeScript type definitions
  * `logger` - Integration logger instance
  * `buildOutput` - The build output mode: `'static'` or `'server'`

  ```js theme={null}
  'astro:config:done': ({ config, setAdapter, injectTypes }) => {
    // Set an adapter
    setAdapter({
      name: 'my-adapter',
      serverEntrypoint: './server.js',
      supportedAstroFeatures: {
        staticOutput: 'stable',
        serverOutput: 'stable'
      }
    });

    // Inject types
    const typesPath = injectTypes({
      filename: 'types.d.ts',
      content: 'declare module "my-integration" { }'
    });
  }
  ```
</ParamField>

### `astro:server:setup`

<ParamField path="hooks['astro:server:setup']" type="function">
  Called during the dev server setup, before the server starts. Allows access to the Vite dev server instance.

  **Parameters:**

  * `server` - The Vite dev server instance
  * `logger` - Integration logger instance
  * `toolbar` - Dev toolbar communication helpers
  * `refreshContent` - Function to refresh content collections (optional)

  ```js theme={null}
  'astro:server:setup': ({ server }) => {
    server.middlewares.use((req, res, next) => {
      // Add custom middleware
      next();
    });
  }
  ```
</ParamField>

### `astro:server:start`

<ParamField path="hooks['astro:server:start']" type="function">
  Called after the dev server has started.

  **Parameters:**

  * `address` - The server address information (host, port, etc.)
  * `logger` - Integration logger instance

  ```js theme={null}
  'astro:server:start': ({ address }) => {
    console.log(`Server running at http://${address.address}:${address.port}`);
  }
  ```
</ParamField>

### `astro:server:done`

<ParamField path="hooks['astro:server:done']" type="function">
  Called when the dev server is closed.

  **Parameters:**

  * `logger` - Integration logger instance

  ```js theme={null}
  'astro:server:done': () => {
    console.log('Dev server closed');
  }
  ```
</ParamField>

### `astro:build:start`

<ParamField path="hooks['astro:build:start']" type="function">
  Called when the build process starts.

  **Parameters:**

  * `logger` - Integration logger instance
  * `setPrerenderer` - Set a custom prerenderer (advanced)

  ```js theme={null}
  'astro:build:start': () => {
    console.log('Build starting...');
  }
  ```
</ParamField>

### `astro:build:setup`

<ParamField path="hooks['astro:build:setup']" type="function">
  Called during the build, allows you to extend the Vite configuration used during the build.

  **Parameters:**

  * `vite` - Vite config for the build
  * `pages` - Map of page paths to their build data
  * `target` - Build target: `'client'` or `'server'`
  * `updateConfig` - Function to update the Vite config
  * `logger` - Integration logger instance

  ```js theme={null}
  'astro:build:setup': ({ vite, target, updateConfig }) => {
    if (target === 'client') {
      updateConfig({
        build: {
          rollupOptions: {
            output: { manualChunks: {} }
          }
        }
      });
    }
  }
  ```
</ParamField>

### `astro:build:generated`

<ParamField path="hooks['astro:build:generated']" type="function">
  Called after a static build has generated all routes and assets.

  **Parameters:**

  * `dir` - The build output directory
  * `logger` - Integration logger instance
  * `routeToHeaders` - Map of routes to their HTTP headers (when adapter supports static headers)

  ```js theme={null}
  'astro:build:generated': ({ dir }) => {
    // Generate additional files in the output directory
    console.log(`Build output: ${dir.pathname}`);
  }
  ```
</ParamField>

### `astro:build:ssr`

<ParamField path="hooks['astro:build:ssr']" type="function">
  Called after an SSR build has completed.

  **Parameters:**

  * `manifest` - The serialized SSR manifest
  * `middlewareEntryPoint` - File path of the emitted middleware
  * `logger` - Integration logger instance

  ```js theme={null}
  'astro:build:ssr': ({ manifest, middlewareEntryPoint }) => {
    // Process SSR build output
  }
  ```
</ParamField>

### `astro:build:done`

<ParamField path="hooks['astro:build:done']" type="function">
  Called after the build has completed and all output files have been written to disk.

  **Parameters:**

  * `pages` - Array of all generated pages with pathname info
  * `dir` - The build output directory
  * `assets` - Map of asset file names to their output URLs
  * `logger` - Integration logger instance

  ```js theme={null}
  'astro:build:done': ({ pages, dir, assets }) => {
    console.log(`Built ${pages.length} pages to ${dir.pathname}`);
  }
  ```
</ParamField>

### `astro:route:setup`

<ParamField path="hooks['astro:route:setup']" type="function">
  Called for each route during routing setup. Allows you to modify route options.

  **Parameters:**

  * `route` - Route options including component path and prerender setting
  * `logger` - Integration logger instance

  ```js theme={null}
  'astro:route:setup': ({ route }) => {
    // Modify route prerender behavior
    if (route.component.includes('blog')) {
      route.prerender = true;
    }
  }
  ```
</ParamField>

### `astro:routes:resolved`

<ParamField path="hooks['astro:routes:resolved']" type="function">
  Called after all routes have been resolved.

  **Parameters:**

  * `routes` - Array of all resolved routes in the project
  * `logger` - Integration logger instance

  ```js theme={null}
  'astro:routes:resolved': ({ routes }) => {
    console.log(`Found ${routes.length} routes`);
  }
  ```
</ParamField>

## Adding Framework Renderers

Use the `addRenderer` function in the `astro:config:setup` hook to add support for UI frameworks:

```js theme={null}
addRenderer({
  name: '@astrojs/react',
  clientEntrypoint: '@astrojs/react/client.js',
  serverEntrypoint: '@astrojs/react/server.js'
});
```

## Injecting Scripts

Use the `injectScript` function to add JavaScript to pages:

```js theme={null}
injectScript('page', `
  console.log('This runs on every page!');
`);
```

Script stages:

* `'before-hydration'` - Imported client-side, before hydration
* `'head-inline'` - Injected into a script tag in the `<head>`
* `'page'` - Injected into the JavaScript bundle of every page
* `'page-ssr'` - Injected into the frontmatter of every Astro page

## Adding Routes

Use the `injectRoute` function to add new routes:

```js theme={null}
injectRoute({
  pattern: '/custom-route',
  entrypoint: './src/custom-route.astro'
});
```

## Adding Middleware

Use the `addMiddleware` function to add middleware:

```js theme={null}
addMiddleware({
  entrypoint: './src/middleware.ts',
  order: 'pre' // or 'post'
});
```

## Client Directives

Add custom client directives for controlling component hydration:

```js theme={null}
addClientDirective({
  name: 'my-directive',
  entrypoint: './directives/my-directive.js'
});
```

## Dev Toolbar Apps

Add custom apps to the Astro dev toolbar:

```js theme={null}
addDevToolbarApp({
  id: 'my-toolbar-app',
  name: 'My App',
  icon: '<svg>...</svg>',
  entrypoint: './toolbar-app.js'
});
```

## TypeScript Types

Inject TypeScript type definitions into the user's project:

```js theme={null}
'astro:config:done': ({ injectTypes }) => {
  injectTypes({
    filename: 'types.d.ts',
    content: `declare module 'my-integration' {
      export function myFunction(): void;
    }`
  });
}
```

## Integration Logger

All hooks receive a `logger` instance for consistent logging:

```js theme={null}
'astro:config:setup': ({ logger }) => {
  logger.info('Setting up integration');
  logger.warn('This is a warning');
  logger.error('This is an error');
}
```

## Building Adapters

Adapters are a special type of integration that set the `adapter` configuration. Use the `setAdapter` function in `astro:config:done`:

```js theme={null}
'astro:config:done': ({ setAdapter }) => {
  setAdapter({
    name: 'my-adapter',
    serverEntrypoint: './server.js',
    previewEntrypoint: './preview.js',
    supportedAstroFeatures: {
      staticOutput: 'stable',
      serverOutput: 'stable',
      hybridOutput: 'stable',
      i18nDomains: 'stable',
      envGetSecret: 'experimental'
    },
    adapterFeatures: {
      buildOutput: 'server',
      staticHeaders: true
    }
  });
}
```

## Adapter Features

### `supportedAstroFeatures`

Defines which Astro features the adapter supports:

* `staticOutput` - Serving static pages
* `serverOutput` - On-demand rendered pages
* `hybridOutput` - Mix of static and on-demand pages
* `i18nDomains` - i18n domain routing
* `envGetSecret` - Retrieving secrets from `astro:env/server`
* `sharpImageService` - Image transformation with Sharp

Each feature can be:

* `'stable'` - Fully supported
* `'experimental'` - Experimental support
* `'deprecated'` - Deprecated support
* `'unsupported'` - Not supported
* `{ support: 'limited', message: 'Custom message' }` - Limited support with explanation

### `adapterFeatures`

Controls adapter-specific build features:

* `buildOutput` - Force `'static'` or `'server'` output
* `middlewareMode` - `'classic'` or `'edge'` middleware execution
* `staticHeaders` - Support for setting headers on static pages

## Complete Integration Example

```js theme={null}
import { fileURLToPath } from 'node:url';

export default function myIntegration(options = {}) {
  return {
    name: 'my-integration',
    hooks: {
      'astro:config:setup': ({ 
        config, 
        command, 
        updateConfig, 
        addRenderer, 
        injectScript,
        logger 
      }) => {
        logger.info('Setting up integration');

        // Add framework support
        addRenderer({
          name: '@my/renderer',
          serverEntrypoint: '@my/renderer/server'
        });

        // Update Vite config
        updateConfig({
          vite: {
            plugins: [/* ... */]
          }
        });

        // Inject client script
        if (command === 'dev') {
          injectScript('page', 'console.log("Dev mode")');
        }
      },
      'astro:config:done': ({ config, logger }) => {
        logger.info(`Config resolved for ${config.site}`);
      },
      'astro:build:done': ({ dir, pages, logger }) => {
        logger.info(`Built ${pages.length} pages to ${dir.pathname}`);
      }
    }
  };
}
```
