diff --git a/package.json b/package.json index 68369fd..0dfdb0c 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "remark-toc": "^9.0.0", "satori": "^0.18.3", "sharp": "^0.34.5", + "slugify": "^1.6.6", "tailwindcss": "^4.1.18" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 22cba37..a81b5d0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,6 +41,9 @@ importers: sharp: specifier: ^0.34.5 version: 0.34.5 + slugify: + specifier: ^1.6.6 + version: 1.6.6 tailwindcss: specifier: ^4.1.18 version: 4.1.18 @@ -2378,6 +2381,10 @@ packages: deprecated: 'SECURITY: Multiple vulnerabilities fixed in 8.0.1 (XML injection, path traversal, command injection, protocol injection). Upgrade immediately: npm install sitemap@8.0.1' hasBin: true + slugify@1.6.6: + resolution: {integrity: sha512-h+z7HKHYXj6wJU+AnS/+IH8Uh9fdcX1Lrhg1/VMdf9PwoBQXFcXiAdsy2tSK0P6gKwJLXp02r90ahUCqHk9rrw==} + engines: {node: '>=8.0.0'} + smol-toml@1.6.0: resolution: {integrity: sha512-4zemZi0HvTnYwLfrpk/CF9LOd9Lt87kAt50GnqhMpyF9U3poDAP2+iukq2bZsO/ufegbYehBkqINbsWxj4l4cw==} engines: {node: '>= 18'} @@ -5406,6 +5413,8 @@ snapshots: arg: 5.0.2 sax: 1.4.1 + slugify@1.6.6: {} + smol-toml@1.6.0: {} source-map-js@1.2.1: {} diff --git a/src/components/Card.astro b/src/components/Card.astro index 1bf61da..c627603 100644 --- a/src/components/Card.astro +++ b/src/components/Card.astro @@ -22,7 +22,9 @@ const { title, description, ...props } = data; "focus-visible:no-underline focus-visible:underline-offset-0", ]} > - + {title} diff --git a/src/layouts/PostDetails.astro b/src/layouts/PostDetails.astro index 6854cf6..cb21908 100644 --- a/src/layouts/PostDetails.astro +++ b/src/layouts/PostDetails.astro @@ -91,7 +91,7 @@ const nextPost = data-pagefind-body >

{title} diff --git a/src/utils/slugify.ts b/src/utils/slugify.ts index f052b02..4fee6be 100644 --- a/src/utils/slugify.ts +++ b/src/utils/slugify.ts @@ -1,5 +1,23 @@ import kebabcase from "lodash.kebabcase"; +import slugify from "slugify"; -export const slugifyStr = (str: string) => kebabcase(str); +/** + * Check if string contains non-Latin characters + */ +const hasNonLatin = (str: string): boolean => /[^\x00-\x7F]/.test(str); + +/** + * Slugify a string using a hybrid approach: + * - For Latin-only strings: use slugify (eg: "E2E Testing" -> "e2e-testing", "TypeScript 5.0" -> "typescript-5.0") + * - For strings with non-Latin characters: use lodash.kebabcase (preserves non-Latin chars) + */ +export const slugifyStr = (str: string): string => { + if (hasNonLatin(str)) { + // Preserve non-Latin characters (e.g., Burmese, Chinese, etc.) + return kebabcase(str); + } + // Handle Latin strings with better number/acronym handling + return slugify(str, { lower: true }); +}; export const slugifyAll = (arr: string[]) => arr.map(str => slugifyStr(str));