diff --git a/.changeset/brown-cats-deliver.md b/.changeset/brown-cats-deliver.md
new file mode 100644
index 0000000000..af1a86bcbb
--- /dev/null
+++ b/.changeset/brown-cats-deliver.md
@@ -0,0 +1,7 @@
+---
+'nextra': patch
+'nextra-theme-blog': patch
+'nextra-theme-docs': patch
+---
+
+allow headings contain links
diff --git a/packages/nextra-theme-blog/src/mdx-theme.tsx b/packages/nextra-theme-blog/src/mdx-theme.tsx
index da61851fd4..b7958e2e0f 100644
--- a/packages/nextra-theme-blog/src/mdx-theme.tsx
+++ b/packages/nextra-theme-blog/src/mdx-theme.tsx
@@ -36,14 +36,15 @@ const createHeaderLink =
({ children, id, ...props }: ComponentProps<'h2'>): ReactElement => {
return (
-
- {children}
+ {children}
+
+
)
}
const A = ({ children, ...props }: ComponentProps<'a'>) => {
- const isExternal = props.href && props.href.startsWith('https://')
+ const isExternal = props.href?.startsWith('https://')
if (isExternal) {
return (
diff --git a/packages/nextra-theme-docs/src/mdx-components.tsx b/packages/nextra-theme-docs/src/mdx-components.tsx
index 235a9a3204..c679462111 100644
--- a/packages/nextra-theme-docs/src/mdx-components.tsx
+++ b/packages/nextra-theme-docs/src/mdx-components.tsx
@@ -85,7 +85,7 @@ const createHeaderLink = (
...props
}: ComponentProps<'h2'>): ReactElement {
setActiveAnchor ??= useSetActiveAnchor()
- const obRef = useRef(null)
+ const obRef = useRef(null)
useEffect(() => {
const heading = obRef.current
@@ -119,8 +119,9 @@ const createHeaderLink = (
)}
{...props}
>
-
- {children}
+ {children}
+
+
)
}
diff --git a/packages/nextra/styles/subheading-anchor.css b/packages/nextra/styles/subheading-anchor.css
index 1e0638e8ec..acf7803143 100644
--- a/packages/nextra/styles/subheading-anchor.css
+++ b/packages/nextra/styles/subheading-anchor.css
@@ -1,18 +1,17 @@
.subheading-anchor {
- @apply absolute;
+ @apply opacity-0 transition-opacity ltr:ml-1 rtl:mr-1;
- & + a {
- @apply text-current no-underline hover:after:opacity-100;
+ span:target + &,
+ :hover > & {
+ @apply no-underline opacity-100;
}
- & + a:after {
- @apply absolute /* for not including # in focus ring border */;
- @apply content-['#'] text-gray-300 px-2 opacity-0 transition-opacity;
- @apply dark:text-neutral-700;
- }
-
- &:target + a:after {
- @apply text-gray-400 opacity-100;
- @apply dark:text-neutral-500;
+ &:after {
+ @apply content-['#'] px-1;
+ @apply text-gray-300 dark:text-neutral-700;
+ span:target + & {
+ @apply text-gray-400;
+ @apply dark:text-neutral-500;
+ }
}
}