Repository navigation
|
I have content for admins only and intend to build the site twice and host the admin build separately (that's still best practice?). Using a React tag, I can hide content in the page, but headers still appear in the TOC. The link to the admin only header does not work as the content is not in the page. Swizzling the TOC is forbidden. How can I prevent the content from appearing in the TOC? To hide admin only content, I set an environment variable and use the following: src/utils/adminUtils.tsx import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
export const canShowAdmin = (): boolean => {
const {siteConfig} = useDocusaurusContext();
return (siteConfig.customFields.IS_ADMIN_BUILD && siteConfig.customFields.IS_ADMIN_BUILD === 'true');
}src/components/AdminText/index.tsx import { PropsWithChildren } from "react";
import { canShowAdmin } from "@site/src/utils/adminUtils";
export const AdminText = ({children}: PropsWithChildren) => {
return (canShowAdmin()) ? children : <></>
}
export default AdminText;docs/my-page.mdx import AdminText from '@site/src/components/AdminText';
# My Page
## Regular Text
Everyone should see this.
<AdminText>
## Admin Only Text
This will only appear on the admin site
</AdminText>When I set the environment variable to admin only, the page content is correct, but the table of contents has both TIA |
Replies: 1 comment 1 reply
I don't think it is forbidden. It should be flagged as "unsafe", which only means that we might need to do component breaking changes. But this is perfectly mine to swizzle, just be aware of the maintenance cost when you do so.
This is because the TOC is extracted statically at build time through a remark plugin. We can't know what Note that hiding things this way is not ideal because even though the admin content is visually hidden, it still is included in your non-admin site in bundles and json files (possible security issue? + heavier site). If you want the content to disappear, it has to be filtered at build time, instead of thanks to React. I would suggest to filter the JSX tags you want through a remark plugin instead, so that the sensitive content completely disappears from the build (and not just being hidden at runtime). Here's an example: import { visit, SKIP } from 'unist-util-visit';
export default function plugin(options) {
const adminMode = options.adminMode;
return async (tree) => {
visit(tree, 'mdxJsxFlowElement', (node, index, parent) => {
if (node.name === 'Admin') {
// if we build in admin mode
// we replace <Admin> tags by their children content
// See https://unifiedjs.com/learn/recipe/remove-node/#replacing-a-node-with-its-children
if (adminMode) {
parent.children.splice(index, 1, ...node.children);
return [SKIP, index];
}
// Else we hide/remove <Admin> nodes
// See https://unifiedjs.com/learn/recipe/remove-node/#removing-a-node
else {
parent.children.splice(index, 1);
return [SKIP, index];
}
}
});
};
}With this, you don't even need a React runtime component anymore because all Demo: https://stackblitz.com/edit/github-rjxeaz?file=remarkAdmin.js,docusaurus.config.ts,docs%2Fintro.mdx yarn clear && ADMIN_MODE=false yarn start
yarn clear && ADMIN_MODE=true yarn startNote: it's important to use the It's also important to run |
I don't think it is forbidden. It should be flagged as "unsafe", which only means that we might need to do component breaking changes. But this is perfectly mine to swizzle, just be aware of the maintenance cost when you do so.
This is because the TOC is extracted statically at build time through a remark plugin. We can't know what
<AdminText>will do at runtime, so we have to keep the items in the TOC.Note that hiding things this way is not ideal because even though the admin content is visually hidden, it still is included in your non-admin site in bundles and jso…