Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(theme): add ability to inject data attributes from query-string - possibility to create an iframe/embed variant of a page #9028

Merged
merged 3 commits into from May 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
27 changes: 21 additions & 6 deletions packages/docusaurus-theme-classic/src/index.ts
Expand Up @@ -26,7 +26,10 @@ const ContextReplacementPlugin = requireFromDocusaurusCore(
// Need to be inlined to prevent dark mode FOUC
// Make sure the key is the same as the one in `/theme/hooks/useTheme.js`
const ThemeStorageKey = 'theme';
// Support for ?docusaurus-theme=dark
const ThemeQueryStringKey = 'docusaurus-theme';
// Support for ?docusaurus-data-mode=embed&docusaurus-data-myAttr=42
const DataQueryStringPrefixKey = 'docusaurus-data-';

const noFlashColorMode = ({
defaultMode,
Expand All @@ -42,19 +45,15 @@ const noFlashColorMode = ({
}

function getQueryStringTheme() {
var theme = null;
try {
theme = new URLSearchParams(window.location.search).get('${ThemeQueryStringKey}')
return new URLSearchParams(window.location.search).get('${ThemeQueryStringKey}')
} catch(e) {}
return theme;
}

function getStoredTheme() {
var theme = null;
try {
theme = localStorage.getItem('${ThemeStorageKey}');
return localStorage.getItem('${ThemeStorageKey}');
} catch (err) {}
return theme;
}

var initialTheme = getQueryStringTheme() || getStoredTheme();
Expand All @@ -77,6 +76,21 @@ const noFlashColorMode = ({
}
})();`;

/* language=js */
const DataAttributeQueryStringInlineJavaScript = `
(function() {
try {
const entries = new URLSearchParams(window.location.search).entries();
for (var [searchKey, value] of entries) {
if (searchKey.startsWith('${DataQueryStringPrefixKey}')) {
var key = searchKey.replace('${DataQueryStringPrefixKey}',"data-")
document.documentElement.setAttribute(key, value);
}
}
} catch(e) {}
})();
`;

// Duplicated constant. Unfortunately we can't import it from theme-common, as
// we need to support older nodejs versions without ESM support
// TODO: import from theme-common once we only support Node.js with ESM support
Expand Down Expand Up @@ -205,6 +219,7 @@ export default function themeClassic(
tagName: 'script',
innerHTML: `
${noFlashColorMode(colorMode)}
${DataAttributeQueryStringInlineJavaScript}
${announcementBar ? AnnouncementBarInlineJavaScript : ''}
`,
},
Expand Down
30 changes: 28 additions & 2 deletions website/docs/styling-layout.mdx
Expand Up @@ -3,6 +3,7 @@ description: A Docusaurus site is a pre-rendered single-page React application.
---

import ColorGenerator from '@site/src/components/ColorGenerator';
import IframeWindow from '@site/src/components/BrowserWindow/IframeWindow';

# Styling and Layout

Expand Down Expand Up @@ -133,8 +134,33 @@ It is possible to initialize the Docusaurus theme directly from a `docusaurus-th

Examples:

- [`https://docusaurus.io/?docusaurus-theme=dark`](https://docusaurus.io/?docusaurus-theme=dark)
- [`https://docusaurus.io/docs/configuration?docusaurus-theme=light`](https://docusaurus.io/docs/configuration?docusaurus-theme=light)
<IframeWindow url="/docs/?docusaurus-theme=dark" />

<IframeWindow url="/docs/configuration?docusaurus-theme=light" />

:::

### Data Attributes {#data-attributes}

It is possible to inject `<html>` data attributes with query string parameters following the `docusaurus-data-<key>` pattern. This gives you the flexibility to style a page differently based on the query string.

For example, let's render one of our pages with a red border and no navbar:

```css title="/src/css/custom.css"
html[data-navbar='false'] .navbar {
display: none;
}

html[data-red-border] div#__docusaurus {
border: red solid thick;
}
```

<IframeWindow url="/docs/?docusaurus-data-navbar=false&docusaurus-data-red-border" />

:::tip Iframe Mode

If you plan to embed some Docusaurus pages on another site though an iframe, it can be useful to create an alternative display mode and use iframe urls such as `https://mysite.com/docs/myDoc?docusaurus-data-mode=iframe`. It is your responsibility to provide the additional styles and decide which UI elements you want to keep or hide.

:::

Expand Down
8 changes: 8 additions & 0 deletions website/src/css/custom.css
Expand Up @@ -230,3 +230,11 @@ div[class^='announcementBar_'] {
[data-theme='dark'] [data-rmiz-modal-overlay='visible'] {
background-color: rgba(0 0 0 / 95%);
}

html[data-navbar='false'] .navbar {
display: none;
}

html[data-red-border] div#__docusaurus {
border: red solid thick;
}