Skip to content

defineIntegration

defineIntegration is a powerful wrapper around the standard Astro Integrations API. It allows to provide extra hooks, functionality and best-practices when creating Astro Integrations.

my-integration/index.ts
import {
createResolver,
defineIntegration,
} from "astro-integration-kit";
import { corePlugins } from "astro-integration-kit/plugins";
import { z } from "astro/zod";
export default defineIntegration({
name: "my-integration",
optionsSchema: z.object({
/** A comment */
foo: z.string().optional().default("bar"),
}),
plugins: [...corePlugins],
setup({ options }) {
const { resolve } = createResolver(import.meta.url);
return {
"astro:config:setup": ({ watchIntegration }) => {
watchIntegration(resolve())
}
}
}
})

Defining an integration

To define an integration, use the defineIntegration utility:

my-integration/index.ts
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

defineIntegration accepts an optionsSchema argument that is a zod schema.

my-integration/index.ts
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!

Using plugins

Plugins allow us (and you!) to make Astro Integration Kit really powerful. It allows to add arguments to built-in hooks in a type-safe way. Get started by using our corePlugins:

my-integration/index.ts
import { defineIntegration } from "astro-integration-kit";
import { corePlugins } from "astro-integration-kit/plugins";
export default defineIntegration({
// ...
plugins: [...corePlugins]
})

Under the hood, those plugins define using definePlugin pass “metadata” as types thanks to generics.

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:

my-integration/index.ts
import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({
// ...
setup() {
return {}
}
})

It accepts an object with data from the integration definition:

my-integration/index.ts
import { defineIntegration } from "astro-integration-kit";
export default defineIntegration({
// ...
setup({ options, name }) {
return {}
}
})

In setup, you’ll want to add any logic that is shared between any hook, for example:

  • Calling createResolver
  • Save the config from astro:config:done to be used in later hooks

It needs to return Astro hooks.

Using non-built-in Astro hooks

Some official Astro integrations, like @astrojs/db, define new integration hooks that are not built into Astro core. Astro Integration Kit does not integrate with those hooks by default as they are optional.

If you want to use those hooks on your integration or plugin, you can import that extra behavior.

Astro DB (@astrojs/db)

my-integration/index.ts
import { defineIntegration } from "astro-integration-kit";
import "astro-integration-kit/extras/db";
export default defineIntegration({
// ...
setup() {
return {
"astro:db:setup": ({ extendDb }) => {
// ...
},
};
},
});