### Install Astro Integration Kit with yarn Source: https://astro-integration-kit.netlify.app/getting-started/installation Use this command to add the `astro-integration-kit` package to your project using the yarn package manager. This provides an alternative installation method for yarn users. ```shell yarn add astro-integration-kit ``` -------------------------------- ### Install Astro Integration Kit with npm Source: https://astro-integration-kit.netlify.app/getting-started/installation Use this command to add the `astro-integration-kit` package to your project using the npm package manager. This is a standard installation method for npm users. ```shell npm install astro-integration-kit ``` -------------------------------- ### Import defineIntegration Utility Source: https://astro-integration-kit.netlify.app/getting-started/installation After successfully installing the package, you can import core utilities like `defineIntegration` into your JavaScript or TypeScript files. This example shows how to import it to start defining your Astro integrations. ```typescript import { defineIntegration } from "astro-integration-kit" ``` -------------------------------- ### Install Astro Integration Kit with pnpm Source: https://astro-integration-kit.netlify.app/getting-started/installation Use this command to add the `astro-integration-kit` package to your project using the pnpm package manager. This is the recommended method for pnpm users. ```shell pnpm add astro-integration-kit ``` -------------------------------- ### Basic Integration Setup Function Source: https://astro-integration-kit.netlify.app/core/define-integration Provides a minimal example of the `setup` function within `defineIntegration`, which is where the core logic of the Astro integration resides. It must return an object containing Astro hooks. ```typescript import { defineIntegration } from "astro-integration-kit"; export default defineIntegration({ // ... setup() { return {hooks: {}} } }) ``` -------------------------------- ### Example: Defining an Integration with `defineIntegration` Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide This snippet illustrates how to define an Astro integration using `defineIntegration`. It includes a `setup` function with an `astro:config:setup` hook and a custom method `something`, demonstrating the structure for creating a new integration. ```TypeScript export const integration defineIntegration({ name: 'some-integration', setup: () => ({ hooks: { 'astro:config:setup': (params) => { // do something }, }, something: (it: string): string => it, }), }); ``` -------------------------------- ### Extend Astro Integration Hooks with Plugins Source: https://astro-integration-kit.netlify.app/core/with-plugins This example demonstrates how to use `withPlugins` to extend an Astro integration's `astro:config:setup` hook with custom parameters, such as `hasVitePlugin`, by including `hasVitePluginPlugin` in the `plugins` array. It shows a basic setup for an integration named 'my-integration'. ```TypeScript import { defineIntegration, withPlugins } 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 }) => {} } }) } }) ``` -------------------------------- ### Accessing Options and Name in Integration Setup Source: https://astro-integration-kit.netlify.app/core/define-integration Demonstrates how to access the `options` and `name` parameters provided to the `setup` function, enabling dynamic logic based on user configuration and integration identity. This allows for shared logic across hooks. ```typescript import { defineIntegration } from "astro-integration-kit"; export default defineIntegration({ // ... setup({ options, name }) { return {hooks: {}} } }) ``` -------------------------------- ### Using watchDirectory in an Astro Integration Source: https://astro-integration-kit.netlify.app/utilities/watch-directory This TypeScript example illustrates the integration of `watchDirectory` within an Astro integration's `setup` function. It demonstrates how to import `defineIntegration`, `createResolver`, and `watchDirectory` from `astro-integration-kit`, and then use `watchDirectory` inside the `astro:config:setup` hook to monitor a directory for changes, triggering a dev server reload. ```TypeScript import { defineIntegration, createResolver, watchDirectory } from "astro-integration-kit"; export default defineIntegration({ // ... setup() { const { resolve } = createResolver(import.meta.url) return { hooks: { "astro:config:setup": (params) => { watchDirectory(params, resolve()) } } } } }) ``` -------------------------------- ### Install and Build Tailwind CSS Stylesheet Source: https://astro-integration-kit.netlify.app/utilities/add-devtoolbar-framework-app Terminal commands to install Tailwind CSS and generate a compiled CSS file. The output file (`./src/styles.css`) will contain all the necessary Tailwind styles for the project, which can then be read and injected into the Astro integration. ```Shell pnpm i tailwindcss pnpm exec tailwindcss -o ./src/styles.css ``` -------------------------------- ### `definePlugin` setup function return value Source: https://astro-integration-kit.netlify.app/core/define-plugin Illustrates that the `setup` function within `definePlugin` must return an object. This object typically contains the Astro hooks that the plugin intends to extend or modify. ```typescript definePlugin({ name: "my-plugin", setup({ name }) { return {} } }) ``` -------------------------------- ### Example: Defining a Utility with `defineUtility` Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide This code snippet demonstrates how to define a utility function using `defineUtility` for the `astro:config:setup` hook. It shows the basic structure for creating a utility that accepts hook parameters and custom options. ```TypeScript export const utility = defineUtility("astro:config:setup")( (params: HookParameters<"astro:config:setup">, options: { name: string }) => { // do something } ); ``` -------------------------------- ### Astro Integration: Basic addDts Usage for Virtual Modules Source: https://astro-integration-kit.netlify.app/utilities/add-dts Illustrates the fundamental way to use `addDts` within an Astro integration's `setup` function and `astro:config:setup` hook. This example defines an integration and adds a type definition for a virtual module named `virtual:my-integration`. ```TypeScript import { defineIntegration, addDts } from "astro-integration-kit"; export default defineIntegration({ // ... setup() { return { hooks: { "astro:config:setup": (params) => { addDts(params, { name: "my-integration", content: `declare module "virtual:my-integration" {}` }) } } } } }) ``` -------------------------------- ### Example package.json with Exports Field Source: https://astro-integration-kit.netlify.app/core/create-resolver This JSON snippet shows a typical `package.json` file with the `exports` field. This field is used to define entry points and expose specific files or directories from a package, often requiring manual updates for new paths. It serves as a contrast to the `createResolver` approach. ```json { "name": "package-name", "exports": { "pages/my-route.astro": "./src/pages/my-route.astro", "plugin.ts": "./src/plugin.ts" } } ``` -------------------------------- ### Basic `definePlugin` structure Source: https://astro-integration-kit.netlify.app/core/define-plugin This snippet shows the fundamental structure for defining an Astro Integration Kit plugin. A plugin requires a `name` and a `setup` function, which serves as the entry point for plugin logic. ```typescript definePlugin({ name: "my-plugin", setup() { // ... } }) ``` -------------------------------- ### Inject a Development Route in Astro Integration Source: https://astro-integration-kit.netlify.app/utilities/inject-dev-route This example demonstrates how to use the `injectDevRoute` utility within an Astro integration's `setup` function. It shows how to define a development-only route with a specific pattern and an entrypoint, ensuring the route is only active during development. ```TypeScript import { defineIntegration, createResolver, injectDevRoute } from "astro-integration-kit"; export default defineIntegration({ // ... setup() { const { resolve } = createResolver(import.meta.url); return { hooks: { "astro:config:setup": (params) => { injectDevRoute(params, { pattern: "/foo", entrypoint: resolve("./pages/foo.astro") }) } } } } }) ``` -------------------------------- ### defineIntegration API Reference Source: https://astro-integration-kit.netlify.app/core/define-integration Detailed API documentation for the `defineIntegration` function, outlining its structure, accepted arguments like `optionsSchema` (for Zod-based option handling) and `setup` (for core integration logic), and their respective functionalities. Caution: Never pass generics manually to `defineIntegration` as it breaks TypeScript magic for options. ```APIDOC defineIntegration(config: object): AstroIntegration config: name: string - Purpose: The name of the integration. optionsSchema?: z.ZodObject - Type: Zod schema (e.g., z.object({ ... })) - Purpose: Defines and validates user options for the integration. Supports JSDoc for documentation and default values. setup(params: object): { hooks: object } - Type: Function - Parameters: - options: object - Purpose: User-defined options, validated against `optionsSchema`. - name: string - Purpose: The name of the integration. - Returns: { hooks: object } - Purpose: An object containing Astro hooks (e.g., "astro:config:setup"). - Purpose: Contains the main logic and lifecycle hooks for the integration. Shared logic can be placed here. ``` -------------------------------- ### Example Vue Component for Astro Dev Toolbar App Source: https://astro-integration-kit.netlify.app/utilities/add-devtoolbar-framework-app This Vue component serves as a simple example of a framework component that could be registered as an Astro Dev Toolbar App using the `addDevToolbarFrameworkApp` utility. It includes a basic script setup with a reactive `count` variable and a template to display and increment the count. ```vue ``` -------------------------------- ### Update definePlugin Signature for Astro Integration Kit Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide This example demonstrates the new signature for `definePlugin`, showing how to define a plugin with a specific hook and its implementation. It includes imports for `AstroConfig`, `Plugin`, `PluginOption`, and `definePlugin`. ```TypeScript import type { AstroConfig } from "astro"; import type { Plugin, PluginOption } from "vite"; import { definePlugin } from "astro-integration-kit"; import { hasVitePlugin } from "../utilities/has-vite-plugin.js"; export const hasVitePluginPlugin = definePlugin({ name: "hasVitePlugin", hook: "astro:config:setup", implementation: (params) => (plugin: string | PluginOption) => hasVitePlugin(params, { plugin }), setup() { return { "astro:config:setup": (params) => ({ hasVitePlugin: (plugin: string | PluginOption) => hasVitePlugin(params, { plugin }), }), }; }, }); ``` -------------------------------- ### Comparing Path Resolution for injectRoute and addDevToolbarApp Source: https://astro-integration-kit.netlify.app/core/create-resolver This TypeScript example illustrates the difference in path resolution when using `createResolver` versus direct string paths (which would typically rely on `package.json` exports). It shows how `createResolver` simplifies specifying entrypoints for `injectRoute` and `addDevToolbarApp` by allowing intuitive relative paths. ```typescript import type { AstroIntegration } from "astro"; import { createResolver } from "astro-integration-kit"; export default function myIntegration(): AstroIntegration { const { resolve } = createResolver(import.meta.url); return { name: "my-integration", hooks: { "astro:config:setup": ({ injectRoute, addDevToolbarApp }) => { injectRoute({ pattern: "/my-route", entrypoint: "package-name/pages/my-route.astro" entrypoint: resolve("./pages/my-route.astro") }) addDevToolbarApp( "package-name/plugin.ts" resolve("./plugin.ts") ) } } } } ``` -------------------------------- ### Usage of addVitePlugin Utility Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide This example shows how to use the `addVitePlugin` utility to add a Vite plugin to the Astro configuration. It demonstrates adding `VitePWA` with a specific configuration. ```TypeScript addVitePlugin({ plugin: VitePWA({ registerType: "autoUpdate" }), config, logger, updateConfig, }); addVitePlugin(params, { plugin: VitePWA({ registerType: "autoUpdate" }), }); ``` -------------------------------- ### Step 1: Call defineUtility with Hook Name Source: https://astro-integration-kit.netlify.app/core/define-utility This snippet illustrates the initial step in using `defineUtility`: calling it with the desired Astro hook name, such as `astro:config:setup`. This action sets up the utility to receive the parameters associated with that specific hook. ```typescript import { defineUtility } from "astro-integration-kit"; export const injectDevRoute = defineUtility("astro:config:setup") ``` -------------------------------- ### Basic Usage of defineAllHooksPlugin Source: https://astro-integration-kit.netlify.app/core/define-plugin This code snippet illustrates the fundamental structure for defining a plugin using `defineAllHooksPlugin`. The `setup` function receives the plugin's `name` and returns a higher-order function. This returned function takes a `hookName` and then returns another function that accepts `hookParameters`, within which the actual plugin API (e.g., `doSomething`) for that specific hook is defined. ```JavaScript defineAllHooksPlugin({ name: "my-plugin", setup({ name }) { return (hookName) => (hookParameters) => ({ doSomething: () => { // ... } }); } }) ``` -------------------------------- ### Updating defineIntegration Setup Function Return Type Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide Illustrates the change in the `defineIntegration`'s `setup` function return type. Previously, it returned only the Astro hooks; now, it expects the full integration object properties, including the `hooks` property within that object. ```TypeScript import { defineIntegration } from "astro-integration-kit"; export default defineIntegration({ name: "my-integration", setup({ name }) { return { hooks: { "astro:config:setup": () => { // ... } } }; } }); ``` -------------------------------- ### Usage of addIntegration Utility Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide This example demonstrates how to use the `addIntegration` utility to programmatically add an Astro integration, passing the integration instance and configuration parameters. ```TypeScript addIntegration({ integration: Vue(), updateConfig, config, logger, }); addIntegration(params, { integration: Vue(), }); ``` -------------------------------- ### Define Astro Integration with Options and DTS Generation Source: https://astro-integration-kit.netlify.app/core/define-integration Demonstrates a complete Astro integration using `defineIntegration`, including schema definition with Zod for `virtualModuleId` and a `setup` hook to add a TypeScript declaration file (`.d.ts`) using `addDts`. ```typescript import { defineIntegration, addDts } from "astro-integration-kit" import { z } from "astro/zod" export default defineIntegration({ name: "my-integration", optionsSchema: z.object({ virtualModuleId: z.string() }), setup({ options, name }) { return { hooks: { "astro:config:setup": (params) => { addDts(params, { name, content: `declare module ${JSON.stringify(options.virtualModuleId)} {}` }) } } } } }) ``` -------------------------------- ### Check integration position relative to another Source: https://astro-integration-kit.netlify.app/utilities/has-integration This advanced example shows how to use `hasIntegration` with `position` and `relativeTo` parameters to check the installation order of integrations. This is useful when two integrations must be installed in a specific sequence for proper functionality, allowing for conditional logic based on their relative placement. ```typescript import { defineIntegration, hasIntegration } from "astro-integration-kit"; export default defineIntegration({ // ... setup({ name }) { return { hooks: { "astro:config:setup": (params) => { const { logger } = params if (hasIntegration(params, { name: "@astrojs/tailwind", position: "before", relativeTo: name })) { logger.info("Tailwind is installed before my-integration"); } if (hasIntegration(params, { name: "astro-env", position: "after", relativeTo: name })) { logger.info("AstroEnv is installed after my-integration"); } if (hasIntegration(params, { name: "astro-expressive-code", position: "before", relativeTo: "@astrojs/mdx" })) { logger.info("Expressive Code is installed before MDX"); } if (hasIntegration(params, { name: "astro-expressive-code", position: "after", relativeTo: "@astrojs/tailwind" })) { logger.info("Expressive Code is installed after Tailwind"); } } } } } }) ``` -------------------------------- ### Astro Integration with Deprecated Dev Toolbar App Registration Source: https://astro-integration-kit.netlify.app/utilities/add-devtoolbar-framework-app This TypeScript code demonstrates an Astro integration that previously used `addDevToolbarFrameworkApp` to register a Vue component as a Dev Toolbar App. It showcases the setup of an Astro integration, including importing necessary utilities like `defineIntegration`, `createResolver`, and `addIntegration`, and then configuring the `astro:config:setup` hook to add a Vue integration and the now-removed `addDevToolbarFrameworkApp`. ```typescript import { defineIntegration, createResolver, addIntegration, addDevToolbarFrameworkApp, } from "astro-integration-kit"; import Vue from "@astrojs/vue"; export default defineIntegration({ // ... setup() { const { resolve } = createResolver(import.meta.url); return { hooks: { "astro:config:setup": (params) => { addIntegration(params, { integration: Vue(), }) addDevToolbarFrameworkApp(params, { framework: "vue", name: "Test Vue Plugin", id: "my-vue-plugin", icon: ``, src: resolve("./my-plugin.vue"), style: `\nh1 {\nfont-family: Inter;\n}\n`, }) } } } } }) ``` -------------------------------- ### Define React Dev Toolbar App Component Source: https://astro-integration-kit.netlify.app/utilities/add-devtoolbar-framework-app Example of a React component for an Astro Dev Toolbar App, demonstrating how to receive `DevToolbarFrameworkAppProps` including `canvas`, `eventTarget`, and `renderWindow` as props. ```tsx import type { DevToolbarFrameworkAppProps } from "astro-integration-kit"; export default function App({ canvas, eventTarget, renderWindow }: DevToolbarFrameworkAppProps) { return
...
} ``` -------------------------------- ### Check if an Astro integration is installed Source: https://astro-integration-kit.netlify.app/utilities/has-integration This snippet demonstrates the basic usage of `hasIntegration` to verify if a particular integration, such as `@astrojs/tailwind`, has been added to the Astro configuration. It's typically used within an integration's `astro:config:setup` hook to conditionally apply logic. ```typescript import { defineIntegration, hasIntegration } from "astro-integration-kit"; export default defineIntegration({ // ... setup() { return { hooks: { "astro:config:setup": (params) => { const { logger } = params if (hasIntegration(params, { name: "@astrojs/tailwind" })) { logger.info("Tailwind is installed!"); } } } } } }) ``` -------------------------------- ### Define injectDevRoute Utility with defineUtility Source: https://astro-integration-kit.netlify.app/core/define-utility This snippet demonstrates the complete definition of the `injectDevRoute` utility using `defineUtility`. It shows how to create a utility that hooks into `astro:config:setup` and conditionally injects a development route based on the Astro command, ensuring type safety for hook parameters. ```typescript 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); } }, ); ``` -------------------------------- ### Step 2: Apply Currying with Typed Hook Parameters Source: https://astro-integration-kit.netlify.app/core/define-utility This snippet shows the second step, applying currying to `defineUtility`. The returned function is called with a callback that receives the typed parameters of the specified Astro hook (e.g., `HookParameters<"astro:config:setup">`), enabling type-safe access to hook arguments. ```typescript import { defineUtility } from "astro-integration-kit"; export const injectDevRoute = defineUtility("astro:config:setup")( // Typed as HookParameters<"astro:config:setup"> (params) => {} ) ``` -------------------------------- ### Update Plugin Type Signature in Astro Integration Kit Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide This snippet illustrates the updated type definition for the `Plugin` interface, specifically detailing its structure for the `astro:config:setup` hook, including parameters and return types for utility functions. ```TypeScript type SomePlugin = Plugin< "utilityName", "astro:config:setup", (params: UtilityParams) => UtilityOutput, { "astro:config:setup": (HookParameters<"astro:config:setup">) => { utilityName: (params: UtilityParams) => UtilityOutput } } >; ``` -------------------------------- ### Define Astro Integration with Vue Framework App Source: https://astro-integration-kit.netlify.app/utilities/add-devtoolbar-framework-app Demonstrates how to define an Astro integration using `defineIntegration`, `createResolver`, `addIntegration`, and `addDevToolbarFrameworkApp`. This example specifically adds the Vue integration and registers a Vue-based Dev Toolbar App, including an inline SVG icon and CSS styling. ```ts import { defineIntegration, createResolver, addIntegration, addDevToolbarFrameworkApp, } from "astro-integration-kit"; import Vue from "@astrojs/vue"; export default defineIntegration({ // ... setup() { const { resolve } = createResolver(import.meta.url); return { hooks: { "astro:config:setup": (params) => { addIntegration(params, { integration: Vue(), }); addDevToolbarFrameworkApp(params, { framework: "vue", name: "Test Vue Plugin", id: "my-vue-plugin", icon: ``, src: resolve("./my-plugin.vue"), style: ` h1 { font-family: Inter; } `, }); }, }, }; }, }); ``` -------------------------------- ### Define Vue Dev Toolbar App Component Source: https://astro-integration-kit.netlify.app/utilities/add-devtoolbar-framework-app Example of a Vue component for an Astro Dev Toolbar App, demonstrating how to define props using `defineProps()` to receive app properties like `canvas`, `eventTarget`, and `renderWindow`. ```vue ``` -------------------------------- ### Step 5: Use defineUtility in an Astro Integration Source: https://astro-integration-kit.netlify.app/core/define-utility This snippet demonstrates how to use the `injectDevRoute` utility within a full Astro integration. It illustrates how to define an integration, set up a resolver for path resolution, and call the utility within the `astro:config:setup` hook to inject a development route, showcasing practical application. ```typescript import { defineIntegration, createResolver, injectDevRoute } from "astro-integration-kit" export const integration = defineIntegration({ name: "my-integration", setup() { const { resolve } = createResolver(import.meta.url) return { hooks: { "astro:config:setup": (params) => { injectDevRoute(params, { pattern: "/", entrypoint: resolve("./pages/index.astro") }) } } } } }) ``` -------------------------------- ### Define Astro Integration with Custom API Source: https://astro-integration-kit.netlify.app/core/define-integration This snippet demonstrates how to define an Astro integration using `defineIntegration` and expose custom properties and methods (like `counter` and `increment`) via the `api` object returned from the `setup` function. It shows how to maintain internal state within the integration and make it accessible. ```TypeScript 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++; } } }; } }); ``` -------------------------------- ### Astro Integration: Migrating from addDts to injectTypes Source: https://astro-integration-kit.netlify.app/utilities/add-dts This snippet demonstrates the deprecated `addDts` utility and its recommended replacement, `params.injectTypes`, for injecting type definitions in Astro integrations. It shows how to transition from the old method within the `astro:config:setup` hook to the new `injectTypes` method in `astro:config:done`. ```TypeScript "astro:config:setup": (params) => { addDts(params, { name: "my-integration", content: `declare module "virtual:my-integration" {}` }) }, "astro:config:done": (params) => { params.injectTypes({ filename: "types.d.ts", content: `declare module "virtual:my-integration" {}` }) } ``` -------------------------------- ### Integrate a custom plugin using `withPlugins` Source: https://astro-integration-kit.netlify.app/core/define-plugin This example demonstrates how to incorporate a custom plugin, `hasVitePluginPlugin`, into an Astro integration. It uses `defineIntegration` and `withPlugins` to attach the plugin, making its injected properties (like `hasVitePlugin`) available within the integration's hooks. ```typescript import { defineIntegration, withPlugins } 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 }) => {} } }) } }) ``` -------------------------------- ### Injecting custom properties into Astro hooks via `definePlugin` Source: https://astro-integration-kit.netlify.app/core/define-plugin This advanced example demonstrates how a `definePlugin` can return an object containing Astro hooks. Within these hooks, additional properties or methods can be injected into the hook context, making them available for use by the integration that consumes the plugin. ```typescript definePlugin({ name: "my-plugin", setup({ name }) { return { "astro:config:setup": ({ updateConfig }) => ({ doSomething: (foo: string) => { updateConfig({ // ... }) } }) } } }) ``` -------------------------------- ### Define Astro Integration with Virtual Imports Source: https://astro-integration-kit.netlify.app/utilities/add-virtual-imports This TypeScript code demonstrates how to use `addVirtualImports` within an Astro integration's `astro:config:setup` hook. It shows two ways to define virtual modules: a simple JSON configuration and context-specific modules for 'server' and 'client' environments, allowing different content based on where the module is imported. ```typescript import { defineIntegration, addVirtualImports } from "astro-integration-kit"; export default defineIntegration({ // ... setup({ name }) { return { hooks: { "astro:config:setup": (params) => { addVirtualImports(params, { name, imports: { 'virtual:my-integration/config': `export default ${JSON.stringify({ foo: "bar" })}`, } }) addVirtualImports(params, { name, imports: [ { id: "virtual:my-integration/advanced", content: "export const foo = 'server'", context: "server" }, { id: "virtual:my-integration/advanced", content: "export const foo = 'client'", context: "client" }, ] }) } } } } }) ``` -------------------------------- ### Define `hasVitePluginPlugin` for Astro Integration Kit Source: https://astro-integration-kit.netlify.app/core/define-plugin This snippet defines `hasVitePluginPlugin` using `definePlugin`. It extends Astro's `astro:config:setup` hook to manage Vite plugins, allowing other parts of the integration to check for existing Vite plugins and update the configuration. It demonstrates how to modify the `updateConfig` function to ensure proper plugin handling. ```typescript import type { AstroConfig } from "astro"; import type { Plugin, PluginOption } from "vite"; import { definePlugin } from "astro-integration-kit"; import { hasVitePlugin, getPlugins } from "../utilities/has-vite-plugin.js"; export const hasVitePluginPlugin = definePlugin({ name: "hasVitePlugin", setup() { return { "astro:config:setup": (params) => { const currentPlugins = getPlugins( new Set(), params.config.vite?.plugins, ); const { updateConfig, config } = params; params.updateConfig = (newConfig) => { config.vite.plugins = Array.from( getPlugins(currentPlugins, newConfig.vite?.plugins), ); return updateConfig(newConfig); }; return { hasVitePlugin: (plugin: string | PluginOption) => hasVitePlugin(params, { plugin, }), }; }, }; }, }); ``` -------------------------------- ### Add Vite Plugin to Astro Integration Configuration Source: https://astro-integration-kit.netlify.app/utilities/add-vite-plugin Demonstrates how to use `addVitePlugin` within an Astro integration's `astro:config:setup` hook to add a Vite plugin, such as `vite-plugin-pwa`, to the Astro configuration. This allows extending Astro's build process with custom Vite functionalities. ```typescript import { defineIntegration, addVitePlugin } from "astro-integration-kit"; import { VitePWA } from 'vite-plugin-pwa' export default defineIntegration({ // ... setup() { return { hooks: { "astro:config:setup": (params) => { addVitePlugin(params, { plugin: VitePWA({ registerType: 'autoUpdate' }) }) } } } } }) ``` -------------------------------- ### Defining an Astro Integration with Virtual Module DTS Source: https://astro-integration-kit.netlify.app/getting-started/usage This TypeScript code snippet illustrates how to define a custom Astro integration using the `defineIntegration` utility. It demonstrates setting up an `optionsSchema` for configuration validation and integrating the `addDts` utility within the `astro:config:setup` hook to generate a TypeScript declaration file for a virtual module, which is crucial for providing type definitions for dynamically created modules. ```TypeScript import { defineIntegration, addDts } from "astro-integration-kit" import { z } from "astro/zod" export default defineIntegration({ name: "my-integration", optionsSchema: z.object({ virtualModuleId: z.string() }), setup({ options, name }) { return { hooks: { "astro:config:setup": (params) => { addDts(params, { name, content: `declare module ${JSON.stringify(options.virtualModuleId)} {}` }) } } } } }) ``` -------------------------------- ### Astro Integration: Generating Dynamic Types with addDts and Interpolation Source: https://astro-integration-kit.netlify.app/utilities/add-dts Demonstrates how to dynamically generate type definitions based on integration options using string interpolation with `addDts`. This example uses `zod` for schema validation and creates a union type for locales based on user configuration, injecting it into a virtual module. ```TypeScript import { defineIntegration, addDts } from "astro-integration-kit"; import { z } from "astro/zod" export default defineIntegration({ // ... optionsSchema: z.object({ locales: z.array(z.string()) }), setup({ options }) { return { hooks: { "astro:config:setup": (params) => { addDts(params, { name: "my-integration", content: `declare module "virtual:my-integration" { export type Locale: ${options.locales.map(e => `"${e}"`).join(" | ")}; }` }) } } } } }) ``` -------------------------------- ### Migrate addVirtualImport to addVirtualImports in Astro Integration Kit (Extended Hooks) Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide This snippet demonstrates how to migrate from the deprecated `addVirtualImport` to `addVirtualImports` when using extended hooks with `astro-integration-kit/plugins`. The old approach involved calling `addVirtualImport` multiple times for individual imports, while the new `addVirtualImports` allows defining multiple virtual imports in a single object within `defineIntegration`'s `setup` method. ```TypeScript import { defineIntegration } from "astro-integration-kit"; import { addVirtualImportsPlugin } from "astro-integration-kit/plugins"; export default defineIntegration({ name: "my-integration", plugins: [addVirtualImportsPlugin], setup() { return { "astro:config:setup": ({ addVirtualImports }) => { addVirtualImports({ 'virtual:my-integration/config': `export default ${JSON.stringify({ foo: "bar" })}`, 'virtual:my-integration/context': `export default ${JSON.stringify({ entrypoint: import.meta.url })}` }) } } } }) ``` -------------------------------- ### Define Custom Fields and API on Astro Integration Source: https://astro-integration-kit.netlify.app/core/with-plugins This snippet illustrates how `withPlugins` can be used to define additional properties, like an `api` object with a `counter`, directly within the integration's return value. This allows external access to the integration's internal state and methods, such as `get counter` and `increment`, providing a way to expose internal state. ```TypeScript 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++; }, }, }); }, }); ``` -------------------------------- ### Detect Vite Plugin using hasVitePluginPlugin with withPlugins in Astro Integration Source: https://astro-integration-kit.netlify.app/utilities/has-vite-plugin This example illustrates using the `hasVitePluginPlugin` with `withPlugins` to check for an existing Vite plugin. This approach is recommended for correct detection of plugins added inside your integration, ensuring `hasVitePluginPlugin` is the first plugin in the `plugins` array. It provides the `hasVitePlugin` function directly in the `params` object. ```TypeScript import { defineIntegration, withPlugins } from "astro-integration-kit"; import { hasVitePluginPlugin } from "astro-integration-kit/plugins"; export default defineIntegration({ // ... setup({ name }) { return withPlugins({ name, plugins: [hasVitePluginPlugin], hooks: { "astro:config:setup": (params) => { const { hasVitePlugin, logger } = params if (hasVitePlugin("vite-plugin-my-integration")) { logger.warn("Vite plugin already exists!"); } } } }) } }) ``` -------------------------------- ### Detect Vite Plugin using hasVitePlugin Utility in Astro Integration Source: https://astro-integration-kit.netlify.app/utilities/has-vite-plugin This example demonstrates how to use the `hasVitePlugin` utility directly within an Astro integration's `astro:config:setup` hook. It checks if a specific Vite plugin has already been added to the Astro configuration and logs a warning if the plugin is found. This method detects plugins added from previously loaded integrations. ```TypeScript import { defineIntegration, hasVitePlugin } from "astro-integration-kit"; export default defineIntegration({ // ... setup() { return { hooks: { "astro:config:setup": (params) => { const { logger } = params if (hasVitePlugin(params, { plugin: "vite-plugin-my-integration" })) { logger.warn("Vite plugin already exists!"); } } } } } }) ``` -------------------------------- ### Migrating HookParameters Import for Astro Integrations Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide Illustrates the updated import path for `HookParameters`, moving from the `astro-integration-kit` package to the native `astro` module for consistency and direct usage of Astro's built-in types. ```TypeScript import type { HookParameters } from 'astro-integration-kit'; import type { HookParameters } from 'astro'; ``` -------------------------------- ### Usage of addDevToolbarFrameworkApp Utility Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide Demonstrates how to use the `addDevToolbarFrameworkApp` utility to register a new framework-specific app for the Astro Dev Toolbar. It shows configuration options such as `framework`, `name`, `id`, `icon`, `src`, and inline `style`. ```TypeScript const { resolve } = createResolver(import.meta.url); addDevToolbarFrameworkApp({ framework: "vue", name: "Test Vue Plugin", id: "my-vue-plugin", icon: ``, src: resolve("./my-plugin.vue"), style: ` h1 { font-family: Inter; } `, config, updateConfig, addDevToolbarApp, injectScript, }); addDevToolbarFrameworkApp(params, { framework: "vue", name: "Test Vue Plugin", id: "my-vue-plugin", icon: ``, src: resolve("./my-plugin.vue"), style: ` h1 { font-family: Inter; } `, }); ``` -------------------------------- ### Deprecated `watchIntegration` Usage in Astro Integration Setup Source: https://astro-integration-kit.netlify.app/dev/hmr-integration This TypeScript code snippet illustrates the previous method of enabling Hot Module Replacement (HMR) within an Astro integration's `setup` hook using `watchIntegration`. This approach is now discouraged due to potential performance issues in production and incompatibility with build steps, as noted in the documentation. ```TypeScript import { defineIntegration, createResolver, watchIntegration } from "astro-integration-kit" export const integration = defineIntegration({ // ... setup() { const { resolve } = createResolver(import.meta.url) return { hooks: { "astro:config:setup": (params) => { watchIntegration(params, resolve()) } } } } }) ``` -------------------------------- ### Add Vite Plugin with Config and Logger Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide Details the updated `addVitePlugin` utility, which now requires `config` and `logger` parameters to enable warnings for duplicate plugins. It also shows how to disable these warnings by setting `warnDuplicate: false`. ```JavaScript "astro:config:setup": ({ config, updateConfig }) => { addVitePlugin({ plugin, config, logger, updateConfig }) } addVitePlugin({ warnDuplicate: false, plugin, updateConfig, }); ``` -------------------------------- ### Migrating from defineIntegration Plugins to withPlugins Utility Source: https://astro-integration-kit.netlify.app/getting-started/upgrade-guide Demonstrates the new approach for handling plugins in Astro integrations. Plugins are no longer passed directly to `defineIntegration` but are now managed using the dedicated `withPlugins` utility, promoting a more modular structure. ```TypeScript import { defineIntegration, withPlugins } from "astro-integration-kit"; import { hasVitePluginPlugin } from "astro-integration-kit/plugins"; export default defineIntegration({ name: "my-integration", plugins: [hasVitePluginPlugin], setup({ name }) { return { "astro:config:setup": ({ hasVitePlugin }) => {}, }; }, }); ``` ```TypeScript import { defineIntegration, withPlugins } 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 }) => {}, }, }); }, }); ```