Files
mypage/lib/remark-internal-links.ts
RJ 91afe03109
Some checks failed
Build and Deploy Next.js Blog to Staging / 🔍 Code Quality Checks (push) Failing after 15s
Build and Deploy Next.js Blog to Staging / 🏗️ Build and Push Docker Image (push) Has been skipped
Build and Deploy Next.js Blog to Staging / 🚀 Deploy to Staging (push) Has been skipped
📄 Huge intl feature
2025-12-02 22:29:24 +00:00

74 lines
1.8 KiB
TypeScript

import { visit } from 'unist-util-visit'
import { Node } from 'unist'
interface LinkNode extends Node {
type: 'link'
url: string
children: Node[]
}
interface Options {
locale?: string
}
/**
* Detects internal blog post links:
* - Relative paths (no http/https)
* - Not absolute paths (doesn't start with /)
* - Ends with .md
*/
function isInternalBlogLink(url: string): boolean {
return (
!url.startsWith('http://') &&
!url.startsWith('https://') &&
!url.startsWith('/') &&
url.includes('.md')
)
}
/**
* Transforms internal .md links to blog routes:
* - tech/article.md → /[locale]/blog/tech/article
* - article.md#section → /[locale]/blog/article#section
* - nested/path/post.md?ref=foo → /[locale]/blog/nested/path/post?ref=foo
*/
function transformToBlogPath(url: string, locale: string = 'en'): string {
// Split into path, hash, and query
const hashIndex = url.indexOf('#')
const queryIndex = url.indexOf('?')
let path = url
let hash = ''
let query = ''
if (hashIndex !== -1) {
path = url.substring(0, hashIndex)
hash = url.substring(hashIndex)
}
if (queryIndex !== -1 && queryIndex < (hashIndex === -1 ? url.length : hashIndex)) {
path = url.substring(0, queryIndex)
query = url.substring(queryIndex, hashIndex === -1 ? url.length : hashIndex)
}
// Remove .md extension
const cleanPath = path.replace(/\.md$/, '')
// Build final URL with locale prefix
return `/${locale}/blog/${cleanPath}${query}${hash}`
}
export function remarkInternalLinks(options: Options = {}) {
const locale = options.locale || 'en'
return (tree: Node) => {
visit(tree, 'link', (node: Node) => {
const linkNode = node as LinkNode
if (isInternalBlogLink(linkNode.url)) {
linkNode.url = transformToBlogPath(linkNode.url, locale)
}
})
}
}