From 946e2cef907a37290bfdf831dedc072de596f927 Mon Sep 17 00:00:00 2001
From: Yangshun Tay <tay.yang.shun@gmail.com>
Date: Sun, 15 Apr 2018 15:50:43 -0700
Subject: [PATCH] Add <doctype HTML> to HTML pages (#566)

* Add doctype to static rendering

* Set content-type for CSS
---
 lib/server/generate.js    | 18 +++++++++---------
 lib/server/renderUtils.js | 21 +++++++++++++++++++++
 lib/server/server.js      | 27 +++++++++++++--------------
 3 files changed, 43 insertions(+), 23 deletions(-)
 create mode 100644 lib/server/renderUtils.js

diff --git a/lib/server/generate.js b/lib/server/generate.js
index f28f03001186..e3e310b7eb9e 100644
--- a/lib/server/generate.js
+++ b/lib/server/generate.js
@@ -11,7 +11,6 @@ function execute() {
   const CWD = process.cwd();
   const fs = require('fs-extra');
   const readMetadata = require('./readMetadata.js');
-  const renderToStaticMarkup = require('react-dom/server').renderToStaticMarkup;
   const path = require('path');
   const color = require('color');
   const toSlug = require('../core/toSlug.js');
@@ -28,6 +27,7 @@ function execute() {
   const join = path.join;
   const sep = path.sep;
   const escapeStringRegexp = require('escape-string-regexp');
+  const {renderToStaticMarkupWithDoctype} = require('./renderUtils');
 
   // create the folder path for a file if it does not exist, then write the file
   function writeFileAndCreateFolder(file, content) {
@@ -180,7 +180,7 @@ function execute() {
         {rawContent}
       </DocsLayout>
     );
-    const str = renderToStaticMarkup(docComp);
+    const str = renderToStaticMarkupWithDoctype(docComp);
 
     const targetFile = join(buildDir, metadata.permalink);
     writeFileAndCreateFolder(targetFile, str);
@@ -198,7 +198,7 @@ function execute() {
           redirect={siteConfig.baseUrl + metadata.permalink}
         />
       );
-      const redirectStr = renderToStaticMarkup(redirectComp);
+      const redirectStr = renderToStaticMarkupWithDoctype(redirectComp);
 
       // create a redirects page for doc files
       const redirectFile = join(
@@ -264,7 +264,7 @@ function execute() {
           {rawContent}
         </BlogPostLayout>
       );
-      const str = renderToStaticMarkup(blogPostComp);
+      const str = renderToStaticMarkupWithDoctype(blogPostComp);
 
       let targetFile = join(buildDir, 'blog', filePath);
       writeFileAndCreateFolder(targetFile, str);
@@ -282,7 +282,7 @@ function execute() {
         config={siteConfig}
       />
     );
-    const str = renderToStaticMarkup(blogPageComp);
+    const str = renderToStaticMarkupWithDoctype(blogPageComp);
 
     let targetFile = join(
       buildDir,
@@ -456,7 +456,7 @@ function execute() {
             continue;
           }
           translate.setLanguage(language);
-          const str = renderToStaticMarkup(
+          const str = renderToStaticMarkupWithDoctype(
             <Site
               language={language}
               config={siteConfig}
@@ -474,7 +474,7 @@ function execute() {
         // write to base level
         let language = env.translation.enabled ? 'en' : '';
         translate.setLanguage(language);
-        const str = renderToStaticMarkup(
+        const str = renderToStaticMarkupWithDoctype(
           <Site language={language} config={siteConfig} metadata={{id: pageID}}>
             <ReactComp language={language} />
           </Site>
@@ -487,7 +487,7 @@ function execute() {
         // allow for rendering of other files not in pages/en folder
         let language = env.translation.enabled ? 'en' : '';
         translate.setLanguage(language);
-        const str = renderToStaticMarkup(
+        const str = renderToStaticMarkupWithDoctype(
           <Site language={language} config={siteConfig} metadata={{id: pageID}}>
             <ReactComp language={language} />
           </Site>
@@ -499,7 +499,7 @@ function execute() {
       const pageID = path.basename(normalizedFile, '.html');
       const parts = normalizedFile.split('pages');
       const targetFile = join(buildDir, parts[1]);
-      const str = renderToStaticMarkup(
+      const str = renderToStaticMarkupWithDoctype(
         <Site language="en" config={siteConfig} metadata={{id: pageID}}>
           <div
             dangerouslySetInnerHTML={{
diff --git a/lib/server/renderUtils.js b/lib/server/renderUtils.js
new file mode 100644
index 000000000000..29dc9873b918
--- /dev/null
+++ b/lib/server/renderUtils.js
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2017-present, Facebook, Inc.
+ *
+ * This source code is licensed under the MIT license found in the
+ * LICENSE file in the root directory of this source tree.
+ */
+
+const renderToStaticMarkup = require('react-dom/server').renderToStaticMarkup;
+
+/**
+ * Custom function that wraps renderToStaticMarkup so that we can inject
+ * doctype before React renders the contents. All instance of full-page
+ * rendering within Docusaurus should use this function instead.
+ */
+function renderToStaticMarkupWithDoctype(...args) {
+  return '<!DOCTYPE html>' + renderToStaticMarkup(...args);
+}
+
+module.exports = {
+  renderToStaticMarkupWithDoctype,
+};
diff --git a/lib/server/server.js b/lib/server/server.js
index 39894e06c492..121af213ff37 100644
--- a/lib/server/server.js
+++ b/lib/server/server.js
@@ -1,5 +1,4 @@
 /**
-
  * Copyright (c) 2017-present, Facebook, Inc.
  *
  * This source code is licensed under the MIT license found in the
@@ -7,27 +6,26 @@
  */
 
 function execute(port) {
-  const extractTranslations = require('../write-translations.js');
+  const extractTranslations = require('../write-translations');
 
   const env = require('./env.js');
-  const translation = require('./translation.js');
+  const translation = require('./translation');
   const express = require('express');
   const React = require('react');
   const request = require('request');
-  const renderToStaticMarkup = require('react-dom/server').renderToStaticMarkup;
   const fs = require('fs-extra');
   const os = require('os');
   const path = require('path');
   const color = require('color');
-  const toSlug = require('../core/toSlug.js');
+  const toSlug = require('../core/toSlug');
   const mkdirp = require('mkdirp');
   const glob = require('glob');
   const chalk = require('chalk');
-  const translate = require('./translate.js');
+  const translate = require('./translate');
+  const {renderToStaticMarkupWithDoctype} = require('./renderUtils');
 
-  const feed = require('./feed.js');
-  const sitemap = require('./sitemap.js');
-  // const sitemap = require("sitemap");
+  const feed = require('./feed');
+  const sitemap = require('./sitemap');
 
   const CWD = process.cwd();
 
@@ -250,7 +248,7 @@ function execute(port) {
       </DocsLayout>
     );
 
-    res.send(renderToStaticMarkup(docComp));
+    res.send(renderToStaticMarkupWithDoctype(docComp));
   });
 
   app.get('/sitemap.xml', function(req, res) {
@@ -293,7 +291,7 @@ function execute(port) {
           config={siteConfig}
         />
       );
-      const str = renderToStaticMarkup(blogPageComp);
+      const str = renderToStaticMarkupWithDoctype(blogPageComp);
 
       let path = (page > 0 ? 'page' + (page + 1) : '') + '/index.html';
       blogPages[path] = str;
@@ -344,7 +342,7 @@ function execute(port) {
           {rawContent}
         </BlogPostLayout>
       );
-      res.send(renderToStaticMarkup(blogPostComp));
+      res.send(renderToStaticMarkupWithDoctype(blogPostComp));
     }
   });
 
@@ -365,7 +363,7 @@ function execute(port) {
       if (siteConfig.wrapPagesHTML) {
         removeModuleAndChildrenFromCache(join('..', 'core', 'Site.js'));
         const Site = require(join('..', 'core', 'Site.js'));
-        const str = renderToStaticMarkup(
+        const str = renderToStaticMarkupWithDoctype(
           <Site
             language="en"
             config={siteConfig}
@@ -436,7 +434,7 @@ function execute(port) {
       removeModuleAndChildrenFromCache(join('..', 'core', 'Site.js'));
       const Site = require(join('..', 'core', 'Site.js'));
       translate.setLanguage(language);
-      const str = renderToStaticMarkup(
+      const str = renderToStaticMarkupWithDoctype(
         <Site
           language={language}
           config={siteConfig}
@@ -507,6 +505,7 @@ function execute(port) {
       });
     }
 
+    res.header('Content-Type', 'text/css');
     res.send(cssContent);
   });