diff --git a/docusaurus.config.ts b/docusaurus.config.ts index 21d6838..0a9763a 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -134,14 +134,17 @@ const config: Config = { { label: 'Home', href: 'https://defined.net', + rel: 'noopener', }, { label: 'Blog', href: 'https://defined.net/blog', + rel: 'noopener', }, { label: 'Docs', href: 'https://docs.defined.net', + rel: 'noopener', }, ], }, diff --git a/package.json b/package.json index f8c05a2..48531c3 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,7 @@ "dependencies": { "@docusaurus/core": "3.9.2", "@docusaurus/preset-classic": "3.9.2", + "@docusaurus/theme-common": "3.9.2", "@mdx-js/react": "^3.1.1", "clsx": "^2.1.1", "parse-domain": "^8.2.2", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 5b55f15..4643371 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -14,6 +14,9 @@ importers: '@docusaurus/preset-classic': specifier: 3.9.2 version: 3.9.2(@algolia/client-search@5.41.0)(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@19.2.4))(@types/react@19.2.2)(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(search-insights@2.17.0)(typescript@5.9.3) + '@docusaurus/theme-common': + specifier: 3.9.2 + version: 3.9.2(@docusaurus/plugin-content-docs@3.9.2(@mdx-js/react@3.1.1(@types/react@19.2.2)(react@19.2.4))(react-dom@19.2.4(react@19.2.4))(react@19.2.4)(typescript@5.9.3))(react-dom@19.2.4(react@19.2.4))(react@19.2.4) '@mdx-js/react': specifier: ^3.1.1 version: 3.1.1(@types/react@19.2.2)(react@19.2.4) @@ -7151,7 +7154,7 @@ snapshots: '@babel/preset-env': 7.28.5(@babel/core@7.28.5) '@babel/preset-react': 7.28.5(@babel/core@7.28.5) '@babel/preset-typescript': 7.28.5(@babel/core@7.28.5) - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 '@babel/runtime-corejs3': 7.28.4 '@babel/traverse': 7.28.5 '@docusaurus/logger': 3.9.2 @@ -9980,7 +9983,7 @@ snapshots: history@4.10.1: dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 loose-envify: 1.4.0 resolve-pathname: 3.0.0 tiny-invariant: 1.3.3 @@ -11774,13 +11777,13 @@ snapshots: react-loadable-ssr-addon-v5-slorber@1.0.1(@docusaurus/react-loadable@6.0.0(react@19.2.4))(webpack@5.102.1): dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 react-loadable: '@docusaurus/react-loadable@6.0.0(react@19.2.4)' webpack: 5.102.1 react-router-config@5.1.1(react-router@5.3.4(react@19.2.4))(react@19.2.4): dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 react: 19.2.4 react-router: 5.3.4(react@19.2.4) @@ -11797,7 +11800,7 @@ snapshots: react-router@5.3.4(react@19.2.4): dependencies: - '@babel/runtime': 7.28.4 + '@babel/runtime': 7.28.6 history: 4.10.1 hoist-non-react-statics: 3.3.2 loose-envify: 1.4.0 diff --git a/src/theme/MDXComponents/A/index.tsx b/src/theme/MDXComponents/A/index.tsx new file mode 100644 index 0000000..251069c --- /dev/null +++ b/src/theme/MDXComponents/A/index.tsx @@ -0,0 +1,31 @@ +import Link from '@docusaurus/Link'; +import { useAnchorTargetClassName } from '@docusaurus/theme-common'; +import type { Props } from '@theme/MDXComponents/A'; +import clsx from 'clsx'; +import React, { type ReactNode } from 'react'; + +export default function MDXA(props: Props): ReactNode { + // MDX Footnotes have ids such as + const anchorTargetClassName = useAnchorTargetClassName(props.id); + + // Customize rel attribute for *.defined.net links + let customRel = props.rel; + let customTarget = props.target; + if (props.href && typeof props.href === 'string') { + try { + const url = new URL(props.href, window.location.href); + // Check if it's an external link to *.defined.net + if (url.hostname.endsWith('.defined.net') || url.hostname === 'defined.net') { + // Override to only use 'noopener' (exclude 'noreferrer') + customRel = 'noopener'; + customTarget = '_blank'; + } + } catch { + // Invalid URL, let default behavior handle it + } + } + + return ( + + ); +}