Skip to content

withPlugins

withPlugins allows you to extend integration hooks with plugins that provide additional parameters and functionality. This is the primary way to use plugins in your integrations.

When you use withPlugins, it:

  1. Resolves plugins: Filters out duplicate plugins (keeping the latest occurrence of plugins with the same name)
  2. Sets up plugins: Calls each plugin’s setup() function with the integration name
  3. Merges hook parameters: For each hook, it collects additional parameters from all applicable plugins and merges them with the original Astro hook parameters
  4. Extends your hooks: Your hook functions receive both the original Astro parameters and the additional parameters provided by plugins
my-integration/index.ts
import { defineIntegration, withPlugins, addVitePlugin } from "astro-integration-kit";
import { hasVitePluginPlugin } from "astro-integration-kit/plugins";
export default defineIntegration({
name: "my-integration",
setup({ name }) {
return withPlugins({
name,
plugins: [hasVitePluginPlugin],
hooks: {
"astro:config:setup": ({ hasVitePlugin, logger }) => {
// hasVitePlugin is provided by the hasVitePluginPlugin
if (hasVitePlugin("some-plugin-name")) {
logger.info("Plugin already exists");
} else {
addVitePlugin(somePlugin());
}
}
}
})
}
})

In this example, the hasVitePluginPlugin adds the hasVitePlugin function to the astro:config:setup hook parameters, which you can then use alongside the original Astro parameters like addVitePlugin and logger.

Astro Integration Kit provides several built-in plugins:

  • hasVitePlugin: Check if a Vite plugin is already present in the configuration

You can also create your own plugins using definePlugin for advanced use cases such as creating reusable plugin components or distributing third-party plugins.

When multiple plugins with the same name are provided, withPlugins automatically deduplicates them by keeping only the last occurrence. This prevents conflicts and ensures predictable behavior.

return withPlugins({
name,
plugins: [pluginA, pluginB, pluginA], // Only the last pluginA is kept
hooks: { /* ... */ }
})

Any extra property (not name, plugins or hooks) passed to withPlugins are returned unchanged.

You can use this to define fields you might want to access from outside your integration while having access to its internal state.

my-integration.ts
import { defineIntegration, withPlugins } from "astro-integration-kit";
export default defineIntegration({
// ...
setup() {
let counter = 0;
return withPlugins({
hooks: {
"astro:config:setup": ({ logger }) => {
logger.info(`Counter: ${counter++}`);
},
},
api: {
get counter() {
return counter;
},
increment() {
counter++;
},
},
});
},
});