mirror of
https://github.com/facebook/docusaurus.git
synced 2025-08-06 02:08:55 +02:00
feat(v2): allow users to specify a custom ssr HTML template (#3387)
* feat(v2): allow users to specify a custom ssr HTML template * docs(v2): add ssrTemplate property to docusaurus.config.js page
This commit is contained in:
parent
9857f7b2b5
commit
3ace60043b
6 changed files with 60 additions and 8 deletions
2
packages/docusaurus-types/src/index.d.ts
vendored
2
packages/docusaurus-types/src/index.d.ts
vendored
|
@ -41,6 +41,7 @@ export interface DocusaurusConfig {
|
|||
[key: string]: unknown;
|
||||
}
|
||||
)[];
|
||||
ssrTemplate?: string;
|
||||
stylesheets?: (
|
||||
| string
|
||||
| {
|
||||
|
@ -110,6 +111,7 @@ export interface LoadContext {
|
|||
siteConfig: DocusaurusConfig;
|
||||
outDir: string;
|
||||
baseUrl: string;
|
||||
ssrTemplate?: string;
|
||||
}
|
||||
|
||||
export interface InjectedHtmlTags {
|
||||
|
|
|
@ -26,19 +26,18 @@ import {
|
|||
createStatefulLinksCollector,
|
||||
ProvideLinksCollector,
|
||||
} from './LinksCollector';
|
||||
import ssrTemplate from './templates/ssr.html.template';
|
||||
|
||||
// eslint-disable-next-line no-restricted-imports
|
||||
import {memoize} from 'lodash';
|
||||
|
||||
const getCompiledSSRTemplate = memoize(() => {
|
||||
return eta.compile(ssrTemplate.trim(), {
|
||||
const getCompiledSSRTemplate = memoize((template) => {
|
||||
return eta.compile(template.trim(), {
|
||||
rmWhitespace: true,
|
||||
});
|
||||
});
|
||||
|
||||
function renderSSRTemplate(data) {
|
||||
const compiled = getCompiledSSRTemplate();
|
||||
function renderSSRTemplate(ssrTemplate, data) {
|
||||
const compiled = getCompiledSSRTemplate(ssrTemplate);
|
||||
return compiled(data, eta.defaultConfig);
|
||||
}
|
||||
|
||||
|
@ -51,6 +50,7 @@ export default async function render(locals) {
|
|||
postBodyTags,
|
||||
onLinksCollected,
|
||||
baseUrl,
|
||||
ssrTemplate,
|
||||
} = locals;
|
||||
const location = routesLocation[locals.path];
|
||||
await preload(routes, location);
|
||||
|
@ -90,7 +90,7 @@ export default async function render(locals) {
|
|||
const stylesheets = (bundles.css || []).map((b) => b.file);
|
||||
const scripts = (bundles.js || []).map((b) => b.file);
|
||||
|
||||
const renderedHtml = renderSSRTemplate({
|
||||
const renderedHtml = renderSSRTemplate(ssrTemplate, {
|
||||
appHtml,
|
||||
baseUrl,
|
||||
htmlAttributes: htmlAttributes || '',
|
||||
|
|
|
@ -81,6 +81,7 @@ const ConfigSchema = Joi.object({
|
|||
// See https://github.com/facebook/docusaurus/issues/3378
|
||||
.unknown(),
|
||||
),
|
||||
ssrTemplate: Joi.string(),
|
||||
stylesheets: Joi.array().items(
|
||||
Joi.string(),
|
||||
Joi.object({
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import {generate} from '@docusaurus/utils';
|
||||
import path, {join} from 'path';
|
||||
import ssrDefaultTemplate from '../client/templates/ssr.html.template';
|
||||
import {
|
||||
BUILD_DIR_NAME,
|
||||
CONFIG_FILE_NAME,
|
||||
|
@ -43,7 +44,7 @@ export function loadContext(
|
|||
const outDir = customOutDir
|
||||
? path.resolve(customOutDir)
|
||||
: path.resolve(siteDir, BUILD_DIR_NAME);
|
||||
const {baseUrl} = siteConfig;
|
||||
const {baseUrl, ssrTemplate} = siteConfig;
|
||||
|
||||
return {
|
||||
siteDir,
|
||||
|
@ -51,6 +52,7 @@ export function loadContext(
|
|||
siteConfig,
|
||||
outDir,
|
||||
baseUrl,
|
||||
ssrTemplate,
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -72,7 +74,7 @@ export async function load(
|
|||
): Promise<Props> {
|
||||
// Context.
|
||||
const context: LoadContext = loadContext(siteDir, customOutDir);
|
||||
const {generatedFilesDir, siteConfig, outDir, baseUrl} = context;
|
||||
const {generatedFilesDir, siteConfig, outDir, baseUrl, ssrTemplate} = context;
|
||||
|
||||
// Plugins.
|
||||
const pluginConfigs: PluginConfig[] = loadPluginConfigs(context);
|
||||
|
@ -237,6 +239,7 @@ ${Object.keys(registry)
|
|||
headTags,
|
||||
preBodyTags,
|
||||
postBodyTags,
|
||||
ssrTemplate: ssrTemplate || ssrDefaultTemplate,
|
||||
};
|
||||
|
||||
return props;
|
||||
|
|
|
@ -31,6 +31,7 @@ export default function createServerConfig({
|
|||
headTags,
|
||||
preBodyTags,
|
||||
postBodyTags,
|
||||
ssrTemplate,
|
||||
} = props;
|
||||
const config = createBaseConfig(props, true, minify);
|
||||
|
||||
|
@ -70,6 +71,7 @@ export default function createServerConfig({
|
|||
preBodyTags,
|
||||
postBodyTags,
|
||||
onLinksCollected,
|
||||
ssrTemplate,
|
||||
},
|
||||
paths: ssgPaths,
|
||||
}),
|
||||
|
|
|
@ -306,6 +306,50 @@ module.exports = {
|
|||
};
|
||||
```
|
||||
|
||||
### `ssrTemplate`
|
||||
|
||||
An HTML template that will be used to render your application. This can be used to set custom attributes on the `body` tags, additional `meta` tags, customize the `viewport`, etc. Please note that Docusaurus will rely on the template to be correctly structured in order to function properly, once you do customize it, you will have to make sure that your template is compliant with the requirements from `upstream`.
|
||||
|
||||
- Type: `string`
|
||||
|
||||
Example:
|
||||
|
||||
```js title="docusaurus.config.js"
|
||||
module.exports = {
|
||||
ssrTemplate: `<!DOCTYPE html>
|
||||
<html <%~ it.htmlAttributes %>>
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=0.86, maximum-scale=3.0, minimum-scale=0.86">
|
||||
<meta name="generator" content="Docusaurus v<%= it.version %>">
|
||||
<%~ it.headTags %>
|
||||
<% it.metaAttributes.forEach((metaAttribute) => { %>
|
||||
<%~ metaAttribute %>
|
||||
<% }); %>
|
||||
<% it.stylesheets.forEach((stylesheet) => { %>
|
||||
<link rel="stylesheet" type="text/css" href="<%= it.baseUrl %><%= stylesheet %>" />
|
||||
<% }); %>
|
||||
<% it.scripts.forEach((script) => { %>
|
||||
<link rel="preload" href="<%= it.baseUrl %><%= script %>" as="script">
|
||||
<% }); %>
|
||||
</head>
|
||||
<body <%~ it.bodyAttributes %> itemscope="" itemtype="http://schema.org/Organization">
|
||||
<%~ it.preBodyTags %>
|
||||
<div id="__docusaurus">
|
||||
<%~ it.appHtml %>
|
||||
</div>
|
||||
<div id="outside-docusaurus">
|
||||
<span>Custom markup</span>
|
||||
</div>
|
||||
<% it.scripts.forEach((script) => { %>
|
||||
<script type="text/javascript" src="<%= it.baseUrl %><%= script %>"></script>
|
||||
<% }); %>
|
||||
<%~ it.postBodyTags %>
|
||||
</body>
|
||||
</html>
|
||||
};
|
||||
```
|
||||
|
||||
### `stylesheets`
|
||||
|
||||
An array of CSS sources to load. The values can be either strings or plain objects of attribute-value maps. The `<link>` tags will be inserted in the HTML `<head>`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue