Skip to content

Instantly share code, notes, and snippets.

@psaia
Last active February 19, 2018 03:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save psaia/125b4e6a55761fd27626cf3046a21387 to your computer and use it in GitHub Desktop.
Save psaia/125b4e6a55761fd27626cf3046a21387 to your computer and use it in GitHub Desktop.
Relay Modern (or anything else) server side rendering for bots.... only.
#!/usr/bin/env node
const fs = require("fs");
const path = require("path");
const express = require("express");
const jsdom = require("jsdom");
const isBot = require("isbot");
const { Script } = require("vm");
const app = express();
const INDEX_FILE = path.normalize(`${__dirname}/../src/www/_index.html`);
const APP_PATH = path.normalize(`${__dirname}/../src/www`);
const readFile = function(path) {
return new Promise((resolve, reject) => {
fs.readFile(path, "utf8", (err, data) => {
if (err) {
reject(err);
} else {
resolve(data);
}
});
});
};
// Server up public files from www/. Notice how index.html is _index.html, so it
// it doesn't get resolved here.
app.use(express.static(APP_PATH));
app.get("*", async function(req, res) {
// If we're in bot territory, serve them a rendered html view so they can
// scrape away. Otherwise, give the user a good experience.
if (isBot(req.headers["user-agent"])) {
console.info("Bot detected. Sending html: " + req.headers["user-agent"]);
const html = await readFile(INDEX_FILE);
// Run scripts, dangerously.
const dom = new jsdom.JSDOM(html, {
url: process.env.APP_URL + req.originalUrl,
pretendToBeVisual: true,
resources: "usable",
runScripts: "dangerously",
beforeParse(window) {
// Add any other window specific func's your app may use.
window.scrollTo = function() {};
window.alert = function() {};
}
});
// You may need to adjust the interval timeout needed for your app
// depending on the kinds of things it's doing to the DOM.
setTimeout(() => res.send(dom.serialize(), 10);
} else {
res.sendFile(INDEX_FILE);
}
});
app.listen(process.env.PORT || 3000);
console.info("Environment:", process.env.NODE_ENV);
console.info("Listening on port ", process.env.PORT);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment