UNPKG

astro-custom-embeds

Version:

Astro integration to easily add your own embeds (that replace matching URLs in mdx files)

103 lines (87 loc) 2.5 kB
import type { AstroConfig, AstroIntegration } from 'astro'; import AutoImport from 'astro-auto-import'; import remarkDirective from 'remark-directive'; import createEmbedPlugin from './remark-plugin.ts'; const importNamespace = 'AuToImPoRtEdAstroCusToMEmbed'; /** * Embeds can be triggered by a single URL or a directive. */ export type EmbedsOption = { componentName: string; /** * path to import component from (default is 'src/components/embeds') */ importPath?: string; /** * for matching single urls on a single line * function that should return a string with the argument to pass to the component or undefined if it doesn't match * * @param url * @returns */ urlMatcher?: (url: string) => string | undefined | null; /** * what argument to pass the url as to the component (default is 'href') */ urlArgument?: string; /** * for matching a directive, name of the directive, can also be an array of names * * @param directive * @returns */ directiveName?: string | string[]; } /** * Astro embed MDX integration. */ export default function customEmbeds({ embeds = [], }: { embeds?: EmbedsOption[] } = {}) { const AstroCustomEmbeds: AstroIntegration = { name: 'astro-custom-embeds', hooks: { 'astro:config:setup': ({ config, updateConfig }) => { checkIntegrationsOrder(config); updateConfig({ markdown: { remarkPlugins: [ remarkDirective, createEmbedPlugin({ embeds, importNamespace }), ], }, }); }, }, }; const imports: Record<string, [string, string][]> = {}; for(const embed of embeds) { let importPath = embed.importPath ?? 'src/components/embeds'; if(!imports[importPath]) { imports[importPath] = []; } imports[importPath].push([embed.componentName, importNamespace + '_' + embed.componentName]); } return [ AutoImport({ imports: [ imports ], }), AstroCustomEmbeds, ]; } function checkIntegrationsOrder({ integrations }: AstroConfig) { const indexOf = (name: string) => integrations.findIndex((i) => i.name === name); const mdxIndex = indexOf('@astrojs/mdx'); const embedIndex = indexOf('astro-custom-embeds'); if (mdxIndex > -1 && mdxIndex < embedIndex) { throw new Error( 'MDX integration configured before astro-custom-embeds.\n' + 'Please move `mdx()` after `customEmbeds()` in the `integrations` array in astro.config.ts.' ); } }