Skip to content

Tailwind Styles

This page shows how to use Tailwind CSS↗ utilities as astro-smart-links class names. Every example can be copied straight into astro.config.mjs; the preview is the real output of that config (examples without an icon disable the default ↗ icon with content: null, see Custom Icons for icon examples).

Distinguish link types with colors and underlines:

Basic Tailwind Styles

Internal Link

External Link

Broken Link

astro.config.mjs
import { smartLinks } from 'astro-smart-links';
smartLinks({
internalLinkClass: 'text-blue-600 hover:text-blue-800 underline transition-colors',
externalLinkClass: 'text-purple-600 hover:text-purple-800 underline transition-colors',
brokenLinkClass: 'text-red-600 hover:text-red-800 line-through transition-colors',
content: null,
}),

Use wrapperTemplate with inline SVG to add an icon to each link type:

Links with Icons

Internal Link

External Link

Broken Link

astro.config.mjs
import { smartLinks } from 'astro-smart-links';
import { h } from 'hastscript';
const icons = {
internal: 'M13 7l5 5m0 0l-5 5m5-5H6',
external: 'M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14',
broken: 'M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
};
smartLinks({
internalLinkClass: 'inline-flex items-center gap-1 text-blue-600 hover:text-blue-800 transition-colors',
externalLinkClass: 'inline-flex items-center gap-1 text-purple-600 hover:text-purple-800 transition-colors',
brokenLinkClass: 'inline-flex items-center gap-1 text-red-600 hover:text-red-800 transition-colors',
wrapperTemplate: (node, type, meta) => {
const svg = h('svg', {
className: 'w-4 h-4',
fill: 'none',
stroke: 'currentColor',
viewBox: '0 0 24 24',
xmlns: 'http://www.w3.org/2000/svg',
}, [
h('path', {
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
'stroke-width': '2',
'd': icons[type],
}),
]);
if (type === 'broken') {
node.children.unshift(svg);
} else {
node.children.push(svg);
}
node.properties.className = [...(node.properties.className || []), meta.className];
return node;
},
}),

Render links as full buttons:

Button-style Links

Internal Link

External Link

Broken Link

astro.config.mjs
import { smartLinks } from 'astro-smart-links';
smartLinks({
internalLinkClass: 'inline-block px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white font-medium rounded-lg transition-colors duration-200',
externalLinkClass: 'inline-block px-4 py-2 bg-purple-600 hover:bg-purple-700 text-white font-medium rounded-lg transition-colors duration-200',
brokenLinkClass: 'inline-block px-4 py-2 bg-red-100 text-red-700 font-medium rounded-lg line-through opacity-75 cursor-not-allowed',
content: null,
}),

Wrap the link in card classes, ideal for article lists and navigation:

Card Links

Internal Link

External Link

Broken Link

astro.config.mjs
import { smartLinks } from 'astro-smart-links';
smartLinks({
internalLinkClass: 'block p-4 rounded-lg border border-base-300 bg-base-100 shadow-sm hover:shadow-md transition-shadow text-blue-600 font-semibold',
externalLinkClass: 'block p-4 rounded-lg border border-base-300 bg-base-100 shadow-sm hover:shadow-md transition-shadow text-purple-600 font-semibold',
brokenLinkClass: 'block p-4 rounded-lg border border-base-300 bg-base-100 shadow-sm text-red-600 font-semibold line-through opacity-75 cursor-not-allowed',
content: null,
}),

Add hover feedback with transition and transform utilities:

Animated Links

Internal Link

External Link

Broken Link

astro.config.mjs
import { smartLinks } from 'astro-smart-links';
smartLinks({
internalLinkClass: 'inline-flex items-center gap-1 text-blue-600 hover:text-blue-800 font-medium transition-transform duration-200 hover:translate-x-1',
externalLinkClass: 'inline-flex items-center gap-1 text-purple-600 hover:text-purple-800 font-medium transition-transform duration-200 hover:-translate-y-0.5',
brokenLinkClass: 'inline-flex items-center gap-1 text-red-600 hover:text-red-700 font-medium line-through transition-transform duration-200 hover:rotate-1',
content: null,
}),

Use the dark: variant to support light and dark themes:

Dark Mode Support

Internal Link

External Link

Broken Link

astro.config.mjs
import { smartLinks } from 'astro-smart-links';
smartLinks({
internalLinkClass: 'text-blue-600 dark:text-blue-400 hover:text-blue-800 dark:hover:text-blue-300 underline transition-colors',
externalLinkClass: 'text-purple-600 dark:text-purple-400 hover:text-purple-800 dark:hover:text-purple-300 underline transition-colors',
brokenLinkClass: 'text-red-600 dark:text-red-400 hover:text-red-800 dark:hover:text-red-300 line-through transition-colors',
content: null,
}),

Turn links into pill-shaped tags:

Badge Links

Internal Link

External Link

Broken Link

astro.config.mjs
import { smartLinks } from 'astro-smart-links';
smartLinks({
internalLinkClass: 'inline-flex items-center px-3 py-1 text-sm rounded-full bg-blue-100 text-blue-700 hover:bg-blue-200 transition-colors duration-200',
externalLinkClass: 'inline-flex items-center px-3 py-1 text-sm rounded-full bg-purple-100 text-purple-700 hover:bg-purple-200 transition-colors duration-200',
brokenLinkClass: 'inline-flex items-center px-3 py-1 text-sm rounded-full bg-red-100 text-red-700 line-through opacity-75 cursor-not-allowed',
content: null,
}),

Combine icons, underlines and transitions into one complete style:

Complete Example

Internal Link

External Link

Broken Link

astro.config.mjs
import { smartLinks } from 'astro-smart-links';
import { h } from 'hastscript';
const icons = {
internal: 'M13 7l5 5m0 0l-5 5m5-5H6',
external: 'M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14',
broken: 'M12 8v4m0 4h.01M21 12a9 9 0 11-18 0 9 9 0 0118 0z',
};
smartLinks({
internalLinkClass: 'inline-flex items-center gap-1 text-blue-600 hover:text-blue-800 underline decoration-2 underline-offset-2 font-medium transition-colors',
externalLinkClass: 'inline-flex items-center gap-1 text-purple-600 hover:text-purple-800 underline decoration-2 underline-offset-2 font-medium transition-colors',
brokenLinkClass: 'inline-flex items-center gap-1 text-red-600 hover:text-red-800 underline decoration-wavy decoration-2 underline-offset-2 font-medium transition-colors',
wrapperTemplate: (node, type, meta) => {
const svg = h('svg', {
className: 'w-4 h-4',
fill: 'none',
stroke: 'currentColor',
viewBox: '0 0 24 24',
xmlns: 'http://www.w3.org/2000/svg',
}, [
h('path', {
'stroke-linecap': 'round',
'stroke-linejoin': 'round',
'stroke-width': '2',
'd': icons[type],
}),
]);
if (type === 'broken') {
node.children.unshift(svg);
} else {
node.children.push(svg);
}
node.properties.className = [...(node.properties.className || []), meta.className];
return node;
},
}),

Keep exploring: