vitepress-alap
VitePress integration for Alap — use <alap-link> web components directly in your markdown documentation.
A Vite plugin that registers <alap-link> as a Vue custom element so the template compiler passes it through instead of dropping it.
Install
npm install alap vitepress-alapSetup
Copy alap.iife.js from the Alap dist into docs/public/. Create a config script in docs/public/docs-config.js. Add both to VitePress head, and add the plugin:
// docs/.vitepress/config.mjs
import { defineConfig } from 'vitepress';
import { alapPlugin } from 'vitepress-alap';
export default defineConfig({
head: [
['script', { src: '/alap.iife.js' }],
['script', { src: '/docs-config.js' }],
],
vite: {
plugins: [alapPlugin()],
},
});The plugin registers <alap-link> as a custom element so Vue's template compiler passes it through. The IIFE and config scripts handle web component registration and config loading.
Config script example
// docs/public/docs-config.js
const alapConfig = {
settings: { listType: 'ul', menuTimeout: 5000 },
allLinks: {
golden: { label: 'Golden Gate Bridge', url: 'https://en.wikipedia.org/wiki/Golden_Gate_Bridge', tags: ['bridge', 'sf'] },
brooklyn: { label: 'Brooklyn Bridge', url: 'https://en.wikipedia.org/wiki/Brooklyn_Bridge', tags: ['bridge', 'nyc'] },
},
macros: {
favorites: { linkItems: 'golden, brooklyn' },
},
};
Alap.registerConfig(alapConfig);
Alap.defineAlapLink();Usage
Use <alap-link> anywhere in your markdown:
Check out these <alap-link query=".coffee">cafes</alap-link>.
The <alap-link query=".nyc + .bridge">NYC bridges</alap-link> are worth visiting.
Browse the <alap-link query="@favorites">favorites</alap-link>.The links render as clickable text. On click, a menu appears with the matching items from your config.
Inline placement
Keep <alap-link> on the same line as surrounding text in markdown. If it starts a new line, the markdown parser treats it as a block element and breaks the paragraph.
Options
| Option | Type | Default | Description |
|---|---|---|---|
config | string | — | Path to config file (auto-injected). Not yet working — use IIFE approach above. |
configName | string | — | Named config for multi-config setups |
validate | boolean | true | Validate config at build time (warns, doesn't fail) |
Styling
Style the web component with ::part() selectors. Add a custom theme file for dark mode support:
/* docs/.vitepress/theme/custom.css */
alap-link {
color: var(--vp-c-brand-1);
text-decoration: underline;
text-decoration-style: dotted;
text-underline-offset: 3px;
cursor: pointer;
}
.dark alap-link {
color: #7eaef5;
}
.dark alap-link::part(menu) {
background: #1e2a48;
border: 1px solid #3a5070;
border-radius: 6px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.4);
}
.dark alap-link::part(link):hover {
background: #2a3d68;
color: #f5c842;
}Register the theme:
// docs/.vitepress/theme/index.js
import DefaultTheme from 'vitepress/theme'
import './custom.css'
export default {
extends: DefaultTheme,
}See Styling for the full guide.
What the plugin does
- Registers
<alap-link>as a custom element in Vue's template compiler — without this, Vue treats it as an unknown component and drops it - Optionally injects the Alap setup script (bundled config path — planned for next beta)
That's it. The web component handles everything else — menus, keyboard nav, ARIA, positioning, dismiss behavior.
Known issues
- Bundled config injection (
alapPlugin({ config: '...' })) does not work yet in VitePress dev mode. Use the IIFE + public scripts approach for now. Fix planned for next beta.
See also
- Web Component guide —
<alap-link>in depth - Astro integration — similar pattern for Astro/Starlight
- Qwik City integration — similar Vite plugin pattern
- Styling — CSS customization with
::part()selectors