defineIntegration
defineIntegration
is a powerful wrapper around the standard Astro Integrations API. It allows integration authors to handle user options and global logic easily.
import { z } from "astro/zod"import { defineIntegration, addVitePlugin } from "astro-integration-kit"import vitePlugin from "vite-plugin"
export default defineIntegration({ name: "my-integration", optionsSchema: z.object({ virtualModuleId: z.string() }), setup({ options, name }) { return { hooks: { "astro:config:setup": (params) => { addVitePlugin(params, { plugin: vitePlugin() }) } } } }})
Defining an integration
Section titled “Defining an integration”To define an integration, use the defineIntegration
utility:
import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({ // ... name: "my-integration"})
It accepts a few arguments, whose usage is explained in the sections below.
Handling options and defaults
Section titled “Handling options and defaults”defineIntegration
accepts an optionsSchema
argument that is a zod
schema.
import { defineIntegration } from "astro-integration-kit";import { z } from "astro/zod";
export default defineIntegration({ // ... optionsSchema: z.object({ /** * A comment * * @default `"bar"` */ foo: z.string().optional().default("bar"), }),})
This way, you can:
- Add proper documentation using JSDoc annotations
- Provide defaults
- Well, take full advantage of
zod
’s power!
Adding the logic with setup
Section titled “Adding the logic with setup”If you’ve written an integration before by returning an AstroIntegration
from a function, it’s exactly
the same with setup
! This is where all the logic lives:
import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({ // ... setup() { return {hooks: {}} }})
It accepts an object with data from the integration definition:
import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({ // ... setup({ options, name }) { return {hooks: {}} }})
In setup, you’ll want to add any logic that is shared between any hook, for example:
- Calling
createResolver
- Save the
config
fromastro:config:done
to be used in later hooks
It needs to return Astro hooks.
Defining extra integration fields
Section titled “Defining extra integration fields”Any extra property present on the return of setup
will be present on the integration object returned by initializing the integration with the options.
You can use this to define fields you might want to access from outside your integration while having access to it’s internal state.
import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({ // ... setup() { let counter = 0; return { hooks: { "astro:config:setup": ({ logger }) => { logger.info(`Counter: ${counter++}`); }, }, api: { get counter() { return counter; }, increment() { counter++; }, }, }; },});
import { defineConfig } from "astro/config";import myIntegration from "./my-integration";
const integration = myIntegration();
console.log(myIntegration.api.counter); // 0
myIntegration.api.increment();
console.log(myIntegration.api.counter); // 1
export default defineConfig({ // Will log "Counter: 1" during setup integrations: [myIntegration],});