Skip to content

Instantly share code, notes, and snippets.

@jacubsmith
Last active February 18, 2021 15:26
Show Gist options
  • Save jacubsmith/528ba61ee86f7d422610b66b349acc9b to your computer and use it in GitHub Desktop.
Save jacubsmith/528ba61ee86f7d422610b66b349acc9b to your computer and use it in GitHub Desktop.
Renders React element and Styled Components (Typescript) into plain HTML and CSS
"prebuild.fallback": "echo 'Preparing build' && rm -rf dist/fallback && webpack --config ./config/webpack.fallback.js",
"build.fallback": "echo 'Building fallback...' && node dist/fallback/fallback.js",
"postbuild.fallback": "echo 'Build completed' && rm dist/fallback/fallback.js"
import 'regenerator-runtime/runtime';
import React from 'react';
import fs from 'fs';
import path from 'path';
import ReactDomServer from 'react-dom/server';
import { ServerStyleSheet, ThemeProvider } from 'styled-components';
import theme from '../theme';
import Fallback from '../routes/Fallback';
const Fallback = () => (
<ThemeProvider theme={theme}>
<Fallback
heading="Browser not compatible"
text="You need to visit the site using a modern version of Chrome, Firefox, Edge or Safari."
/>
</ThemeProvider>
);
const sheetFallback = new ServerStyleSheet();
try {
const htmlFallback = ReactDomServer.renderToStaticMarkup(sheetFallback.collectStyles(<Fallback />));
const styleTagsFallback = sheetFallback.getStyleTags();
const commonContent = `
<meta charset="UTF-8">
<style>
html {
box-sizing: border-box;
}
*,:after,:before {
box-sizing: inherit
}
html, body { margin: 0; padding: 0; font-family: 'Helvetica', sans-serif }; }
</style>
`;
const pageHtmlFallback = `
${commonContent}
${styleTagsFallback}
${htmlFallback}`;
fs.writeFileSync(path.resolve(__dirname, 'fallback.html'), pageHtmlFallback);
} catch (error) {
// handle error
console.error(error);
} finally {
sheetFallback.seal();
}
const path = require('path');
module.exports = {
mode: 'production',
entry: {
fallback: {
import: path.resolve(__dirname, '../src', 'fallback/generate-fallback.tsx'),
filename: 'fallback.js',
},
},
target: 'node',
output: {
path: path.resolve(__dirname, '../', 'dist/fallback'),
filename: 'fallback.js',
publicPath: '/fallback',
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: path.resolve(__dirname, '../node_modules/'),
use: [
{
loader: 'babel-loader',
options: {
cacheDirectory: true,
},
},
],
},
{
test: /\.(ts|tsx)$/,
use: 'ts-loader',
exclude: path.resolve(__dirname, '../node_modules/'),
},
{
test: /\.svg$/,
use: [
{
loader: 'babel-loader',
},
{
loader: 'react-svg-loader',
options: {
jsx: true,
},
},
],
},
],
},
resolve: {
extensions: ['.tsx', '.ts', '.js'],
},
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment