Migration guide
hmrIntegration
Section titled “hmrIntegration”Remove any mention of hmrIntegration, there is no replacement provided:
import { defineConfig } from "astro/config";import myIntegration from "my-integration";import { hmrIntegration } from "astro-integration-kit/dev";
export default defineConfig({ integrations: [ myIntegration(), hmrIntegration({ directory: "../package/dist" }) ],});importFresh
Section titled “importFresh”Remove any mention of importFresh, there is no replacement provided:
import { defineConfig } from "astro/config";import { importFresh } from "astro-integration-kit/dev";const { default: myIntegration } = await importFresh<typeof import("my-integration")>("my-integration");import myIntegration from "my-integration";
export default defineConfig({ integrations: [ myIntegration(), ],});defineIntegration
Section titled “defineIntegration”Simple integration
Section titled “Simple integration”Replace defineIntegration with a function:
import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({ name: "my-integration", setup() { return { hooks: { // ... } } }})import type { AstroIntegration } from "astro";
export default function integration(): AstroIntegration { return { name: "my-integration", hooks: {} }}Options
Section titled “Options”For simple cases, just use a type:
import { defineIntegration } from "astro-integration-kit";import { z } from "astro/zod";
export default defineIntegration({ name: "my-integration", optionsSchema: z.object({ foo: z.string() }), setup(options) { return { hooks: { // ... } } }})import type { AstroIntegration } from "astro";
interface Options { foo: string;}
export default function integration(options: Options): AstroIntegration { return { name: "my-integration", hooks: {} }}Otherwise use a zod schema:
import { z } from "astro/zod";
const OptionsSchema = z.object({ foo: z.string() })
import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({ name: "my-integration", optionsSchema: OptionsSchema, setup(options) { return { hooks: { // ... } } }})import type { AstroIntegration } from "astro";
export default function integration(rawOptions: z.input<typeof OptionsSchema>): AstroIntegration { const options = OptionsSchema.parse(rawOptions); return { name: "my-integration", hooks: {} }}Extra fields
Section titled “Extra fields”Use TypeScript satisfies keyword:
import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({ name: "my-integration", setup() { let counter = 0; return { hooks: { "astro:config:setup": ({ logger }) => { logger.info(`Counter: ${counter++}`); }, }, api: { get counter() { return counter; }, increment() { counter++; }, }, }; },});import type { AstroIntegration } from "astro";
export default function integration() { let counter = 0;
return { name: "my-integration", hooks: { "astro:config:setup": ({ logger }) => { logger.info(`Counter: ${counter++}`); }, }, api: { get counter() { return counter; }, increment() { counter++; }, }, } satisfies AstroIntegration;}createResolver
Section titled “createResolver”Use native URLs instead:
import { createResolver } from "astro-integration-kit";const { resolve } = createResolver(import.meta.url);
// ...injectRoute({ pattern: "/my-route", entrypoint: resolve("./pages/my-route.astro"), entrypoint: new URL("./pages/my-route.astro", import.meta.url),});defineUtility
Section titled “defineUtility”Replace it with a function requiring as few options as possible:
import type { InjectedRoute } from "astro";import { defineUtility } from "astro-integration-kit";
export const injectDevRoute = defineUtility("astro:config:setup")( ({ command, injectRoute }, injectedRoute: InjectedRoute) => { if (command === "dev") { injectRoute(injectedRoute); } },);import type { HookParameters, InjectedRoute } from "astro";
export function injectDevRoute( params: Pick<HookParameters<"astro:config:setup">, "command" | "injectRoute">, injectedRoute: InjectedRoute,) { if (command === "dev") { injectRoute(injectedRoute); }}withPlugins
Section titled “withPlugins”Remove any mention of hmrIntegration, there is no replacement provided. Prefer simple functions.
definePlugin
Section titled “definePlugin”Remove any mention of definePlugin, there is no replacement provided. Prefer simple functions.
addIntegration
Section titled “addIntegration”Use updateConfig() instead:
import { addIntegration } from "astro-integration-kit";import vue from "@astrojs/vue";
// ...hooks: { "astro:config:setup": (params) => { addIntegration(params, { integration: vue() }) params.updateConfig({ integrations: [vue()] }) }}addVirtualImports
Section titled “addVirtualImports”Use a standard Vite plugin instead:
import { addVirtualImports } from "astro-integration-kit";import type { Plugin } from "vite";
const VIRTUAL_MODULE_ID = "virtual:my-integration/config"const RESOLVED_VIRTUAL_MODULE_ID = '\0' + VIRTUAL_MODULE_ID;
function createPlugin(): Plugin { return { name: VIRTUAL_MODULE_ID, resolveId: { filter: { id: new RegExp(`^${VIRTUAL_MODULE_ID}$`), }, handler() { return RESOLVED_VIRTUAL_MODULE_ID; }, }, load: { filter: { id: new RegExp(`^${RESOLVED_VIRTUAL_MODULE_ID}$`), }, handler() { return `export default ${JSON.stringify({ foo: "bar" })}` }, }, };}
// ...hooks: { "astro:config:setup": (params) => { addVirtualImports(params, { name, imports: { 'virtual:my-integration/config': `export default ${JSON.stringify({ foo: "bar" })}`, } }) params.updateConfig({ vite: { plugins: [createPlugin()] } })}Server and client restrictions can be achieved by returning different contents based on this.environment.name:
load: { filter: { id: new RegExp(`^${RESOLVED_VIRTUAL_MODULE_ID}$`), }, handler() { if (this.environment.name === "client") { return "export const foo = 'client'" } return "export const foo = 'server'" },},addVitePlugin
Section titled “addVitePlugin”Use updateConfig() instead:
import { addVitePlugin } from "astro-integration-kit";import { VitePWA } from 'vite-plugin-pwa'
// ...hooks: { "astro:config:setup": (params) => { addVitePlugin(params, { plugin: VitePWA() }) params.updateConfig({ vite: { plugins: [VitePWA()] }}) }}hasVitePlugin
Section titled “hasVitePlugin”Replace with a check based on config:
import { hasVitePlugin } from "astro-integration-kit";
// ...hooks: { "astro:config:setup": (params) => { if (hasVitePlugin(params, { plugin: "foo" })) { if (params.config.vite.plugins.some(e => e.name === "foo")) { // ... } }}hasIntegration
Section titled “hasIntegration”Replace with a check based on config:
import { hasIntegration } from "astro-integration-kit";
// ...hooks: { "astro:config:setup": (params) => { if (hasIntegration(params, { name: "foo" })) { if (params.config.integrations.some(e => e.name === "foo")) { // ... } }}injectDevRoute
Section titled “injectDevRoute”Replace with a conditional call to injectRoute():
import { injectDevRoute } from "astro-integration-kit";
// ...hooks: { "astro:config:setup": (params) => { if (params.command === "dev") { injectDevRoute(params, { injectRoute({ pattern: "/foo", entrypoint: "my-pkg/foo" }) } }}watchDirectory
Section titled “watchDirectory”Remove any mention of watchDirectory, there is no replacement provided.