Advanced Features Demo
This page demonstrates the advanced features and customization options of the rehype-smart-links plugin.
Custom Link Structure
Using the wrapperTemplate
option, you can customize the HTML structure of links. For example, add icons, status indicators, or other elements.
Custom Link Display
// astro.config.mjs
import { defineConfig } from 'astro/config';
import rehypeSmartLinks from 'rehype-smart-links';
import { h } from 'hastscript';
export default defineConfig({
markdown: {
rehypePlugins: [[
rehypeSmartLinks,
{
// Custom link template
wrapperTemplate: (node, linkType) => {
if (linkType === 'internal') {
// Add document icon to internal links
const icon = h('span', { className: 'ml-1' }, '📄');
node.children.push(icon);
node.properties.className = [
...(node.properties.className || []),
'flex',
'items-center'
];
} else if (linkType === 'external') {
// Add link icon to external links
const icon = h('span', { className: 'ml-1' }, '🔗');
node.children.push(icon);
node.properties.className = [
...(node.properties.className || []),
'flex',
'items-center'
];
} else if (linkType === 'broken') {
// Add warning icon to broken links
const icon = h('span', { className: 'mr-1' }, '⚠️');
node.children = [icon, ...node.children];
node.properties.className = [
...(node.properties.className || []),
'flex',
'items-center'
];
}
return node;
}
}
]]
}
});
Adding Badges
You can use wrapperTemplate to add different style badges to links:
Adding Badges to Links
Internal Link
External Link
Broken Link
// astro.config.mjs
import { defineConfig } from 'astro/config';
import rehypeSmartLinks from 'rehype-smart-links';
import { h } from 'hastscript';
export default defineConfig({
markdown: {
rehypePlugins: [[
rehypeSmartLinks,
{
wrapperTemplate: (node, linkType) => {
let badge;
if (linkType === 'internal') {
badge = h('span', {
className: 'badge badge-primary badge-sm'
}, 'Internal');
} else if (linkType === 'external') {
badge = h('span', {
className: 'badge badge-secondary badge-sm'
}, 'External');
} else if (linkType === 'broken') {
badge = h('span', {
className: 'badge badge-error badge-sm'
}, 'Broken');
}
if (badge) {
node.children.push(badge);
node.properties.className = [
...(node.properties.className || []),
'flex',
'items-center',
'gap-2'
];
}
return node;
}
}
]]
}
});
Link Transformation Function
Use the transformLink
option to modify link attributes or content:
Link Transformation Example
// astro.config.mjs
import { defineConfig } from 'astro/config';
import rehypeSmartLinks from 'rehype-smart-links';
export default defineConfig({
markdown: {
rehypePlugins: [[
rehypeSmartLinks,
{
transformLink: (node, linkType, url) => {
// Add specific attributes based on link type and URL
if (linkType === 'internal') {
// Redirect documentation links
if (url.startsWith('/docs/')) {
node.properties.href = url.replace('/docs/', '/documentation/');
}
// Add data attributes
if (url.includes('getting-started')) {
node.properties['data-section'] = 'docs';
}
}
else if (linkType === 'external') {
// Add extra attributes to external links
node.properties['data-external'] = 'true';
// Add special class for specific sites
if (url.includes('github.com')) {
node.properties.className = [
...(node.properties.className || []),
'github-link'
];
}
}
else if (linkType === 'broken') {
// Add error information to broken links
node.properties['data-error'] = 'true';
node.properties.title = 'This page does not exist';
}
return node;
}
}
]]
}
});
Complete Custom Configuration Example
Here is a complete configuration example showing how to combine multiple customization options:
// astro.config.mjs
import { defineConfig } from 'astro/config';
import rehypeSmartLinks from 'rehype-smart-links';
import { h } from 'hastscript';
export default defineConfig({
markdown: {
rehypePlugins: [[
rehypeSmartLinks,
{
// Basic style classes
internalLinkClass: 'custom-internal-link',
brokenLinkClass: 'custom-broken-link',
externalLinkClass: 'custom-external-link',
// Routes file path (matching CLI generated path)
routesFile: './.smart-links-routes.json',
// Whether to include all file types
includeAllFiles: true,
// External link attributes
externalLinkAttributes: {
target: '_blank',
rel: 'noopener noreferrer',
'data-external': 'true'
},
// Custom link structure
wrapperTemplate: (node, linkType, url) => {
// Add icons and styles for different link types
// Implementation code...
return node;
},
// Link transformation function
transformLink: (node, linkType, url) => {
// Modify link attributes based on URL or type
// Implementation code...
return node;
}
}
]]
}
});
Next Steps
Explore more examples:
- CSS Custom Styling - Learn how to customize link styles with CSS
- Custom Icons - Learn how to add custom icons to links