diff --git a/docusaurus.config.js b/docusaurus.config.js
index 8655389dd..c1d91abd1 100644
--- a/docusaurus.config.js
+++ b/docusaurus.config.js
@@ -82,6 +82,11 @@ const config = {
({
metadata: [
{name: 'keywords', content: 'Free, Open-source, Q&A Platform, Knowledge Sharing Platform, Community Forum, Knowledge Base, Developer Hub, Support Center'},
+ {
+ name: 'http-equiv',
+ content: 'Content-Security-Policy',
+ value: "default-src 'self' data: blob: 'unsafe-inline' https://www.apachecon.com/ https://www.communityovercode.org/ https://analytics.apache.org/ https://api-js.mixpanel.com/track/; connect-src https://api-js.mixpanel.com/track/;"
+ }
],
colorMode: {
defaultMode: 'light',
diff --git a/src/theme/Heading/index.tsx b/src/theme/Heading/index.tsx
new file mode 100644
index 000000000..1384e0238
--- /dev/null
+++ b/src/theme/Heading/index.tsx
@@ -0,0 +1,63 @@
+/**
+ * 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 from 'react';
+import clsx from 'clsx';
+import {translate} from '@docusaurus/Translate';
+import {useThemeConfig} from '@docusaurus/theme-common';
+import Link from '@docusaurus/Link';
+import useBrokenLinks from '@docusaurus/useBrokenLinks';
+import type {Props} from '@theme/Heading';
+
+import styles from './styles.module.css';
+
+export default function Heading({as: As, id, ...props}: Props): JSX.Element {
+ const brokenLinks = useBrokenLinks();
+ const {
+ navbar: {hideOnScroll},
+ } = useThemeConfig();
+ // H1 headings do not need an id because they don't appear in the TOC.
+ if (As === 'h1' || !id) {
+ return ;
+ }
+
+ brokenLinks.collectAnchor(id);
+
+ const anchorTitle = translate(
+ {
+ id: 'theme.common.headingLinkTitle',
+ message: 'Direct link to {heading}',
+ description: 'Title for link to heading',
+ },
+ {
+ heading: typeof props.children === 'string' ? props.children : id,
+ },
+ );
+
+ return (
+
+
+ {props.children}
+
+
+
+
+ );
+}
diff --git a/src/theme/Heading/styles.module.css b/src/theme/Heading/styles.module.css
new file mode 100644
index 000000000..1b7c5cdbd
--- /dev/null
+++ b/src/theme/Heading/styles.module.css
@@ -0,0 +1,35 @@
+/**
+ * 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 anchor click,
+the browser does not scroll that anchor behind the navbar
+See https://twitter.com/JoshWComeau/status/1332015868725891076
+ */
+.anchorWithStickyNavbar {
+ scroll-margin-top: calc(var(--ifm-navbar-height) + 0.5rem);
+}
+
+.anchorWithHideOnScrollNavbar {
+ scroll-margin-top: 0.5rem;
+}
+
+:global(.hash-link) {
+ opacity: 0;
+ padding-left: 0.5rem;
+ transition: opacity var(--ifm-transition-fast);
+ user-select: none;
+}
+
+:global(.hash-link::before) {
+ content: '#';
+}
+
+:global(.hash-link:focus),
+:global(*:hover > .hash-link) {
+ opacity: 1;
+}