diff --git a/packages/docusaurus-theme-classic/src/theme-classic.d.ts b/packages/docusaurus-theme-classic/src/theme-classic.d.ts
index a23b1bd8aa..c801c97e79 100644
--- a/packages/docusaurus-theme-classic/src/theme-classic.d.ts
+++ b/packages/docusaurus-theme-classic/src/theme-classic.d.ts
@@ -1040,7 +1040,9 @@ declare module '@theme/SkipToContent' {
declare module '@theme/MDXComponents/A' {
import type {ComponentProps, ReactNode} from 'react';
- export interface Props extends ComponentProps<'a'> {}
+ export interface Props extends ComponentProps<'a'> {
+ 'data-footnote-ref'?: true;
+ }
export default function MDXA(props: Props): ReactNode;
}
diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/A.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/A.tsx
deleted file mode 100644
index 75fe616e66..0000000000
--- a/packages/docusaurus-theme-classic/src/theme/MDXComponents/A.tsx
+++ /dev/null
@@ -1,14 +0,0 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import React, {type ReactNode} from 'react';
-import Link from '@docusaurus/Link';
-import type {Props} from '@theme/MDXComponents/A';
-
-export default function MDXA(props: Props): ReactNode {
- return ;
-}
diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/A/index.tsx b/packages/docusaurus-theme-classic/src/theme/MDXComponents/A/index.tsx
new file mode 100644
index 0000000000..21e4dac8bd
--- /dev/null
+++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/A/index.tsx
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+import React, {type ReactNode} from 'react';
+import clsx from 'clsx';
+import Link from '@docusaurus/Link';
+import {useThemeConfig} from '@docusaurus/theme-common';
+import type {Props} from '@theme/MDXComponents/A';
+import styles from './styles.module.css';
+
+function isFootnoteRef(props: Props) {
+ return props['data-footnote-ref'] === true;
+}
+
+function FootnoteRefLink(props: Props) {
+ const {
+ navbar: {hideOnScroll},
+ } = useThemeConfig();
+ return (
+
+ );
+}
+
+export default function MDXA(props: Props): ReactNode {
+ if (isFootnoteRef(props)) {
+ return ;
+ }
+ return ;
+}
diff --git a/packages/docusaurus-theme-classic/src/theme/MDXComponents/A/styles.module.css b/packages/docusaurus-theme-classic/src/theme/MDXComponents/A/styles.module.css
new file mode 100644
index 0000000000..295757363a
--- /dev/null
+++ b/packages/docusaurus-theme-classic/src/theme/MDXComponents/A/styles.module.css
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) Facebook, Inc. and its affiliates.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+/*
+When the navbar is sticky, ensure that on footnote click,
+the browser does not scroll to the ref behind the navbar
+See https://github.com/facebook/docusaurus/issues/11232
+See also headings case https://x.com/JoshWComeau/status/1332015868725891076
+ */
+.footnoteRefStickyNavbar {
+ scroll-margin-top: calc(var(--ifm-navbar-height) + 0.5rem);
+}
+
+.footnoteRefHideOnScrollNavbar {
+ scroll-margin-top: 0.5rem;
+}