Commit 261053c

HPCesia <me@hpcesia.com>
2026-03-11 07:44:27
External links process
1 parent 6989627
Changed files (2)
src/plugins/rehype-external-links.ts
@@ -0,0 +1,25 @@
+import type { RehypePlugin } from "@astrojs/markdown-remark";
+import { visit } from "unist-util-visit";
+import { SITE_CONFIG } from "../config";
+
+export const rehypeExternalLinks: RehypePlugin =
+  (options?: { protocols?: string[] }) => (tree) => {
+    visit(tree, "element", (node) => {
+      if (node.tagName === "a" && typeof node.properties?.href === "string") {
+        const href = node.properties.href;
+        const protocol = href.split("://")[0].toLowerCase();
+        const allowedProtocols = options?.protocols || ["http", "https"];
+        if (!allowedProtocols.includes(protocol)) return;
+
+        const siteWithoutProtocol = SITE_CONFIG.website.replace(
+          /^https?:\/\//,
+          "",
+        );
+        const hrefWithoutProtocol = href.split("://")[1] || href;
+        if (hrefWithoutProtocol.startsWith(siteWithoutProtocol)) return;
+
+        node.properties.target = "_blank";
+        node.properties.rel = "noopener noreferrer nofollow";
+      }
+    });
+  };
astro.config.ts
@@ -4,6 +4,7 @@ import { typst } from "astro-typst";
 import { SITE_CONFIG } from "./src/config";
 import { extractImage } from "./src/integrations/extract-image";
 import { rehypeCleanEndnotes } from "./src/plugins/rehype-clean-endnotes";
+import { rehypeExternalLinks } from "./src/plugins/rehype-external-links";
 
 // https://astro.build/config
 export default defineConfig({
@@ -20,7 +21,7 @@ export default defineConfig({
     }),
   ],
   markdown: {
-    rehypePlugins: [rehypeCleanEndnotes],
+    rehypePlugins: [rehypeCleanEndnotes, rehypeExternalLinks],
   },
   vite: {
     plugins: [tailwindcss()],