I am using rendertron as a solution for server side rendering, below is index.js file. How to execute index.js and where to execute. I have setup my own instance of redertron using docker on my server and my angular app build is within dist folder how to render complete html of my angular app using rendertron and where to execute index.js
const express = require('express');
const fetch = require('node-fetch');
const url = require('url');
const app = express('');
const appUrl = 'http://xyzabc.com';
const renderUrl = 'http://pqr.com/render';
function generateUrl(request) {
return url.format({
protocol: request.protocol,
host: appUrl,
pathname: request.originalUrl
});
}
function detectBot(userAgent){
const bots = [
'bingbot',
'yandexbot',
'duckduckbot',
'slurp',
//Social
'twitterbot',
'facebookexternalhit',
'linkedinbot',
'embedly',
'pinterest',
'W3C_Validator'
]
const agent = userAgent.toLowerCase();
for (const bot of bots) {
if (agent.indexOf(bot) > -1) {
console.log('bot detected', bot, agent);
return true;
}
}
console.log('no bots found');
return false;
}
app.get('*', (req, res) =>{
const isBot = detectBot(req.headers['user-agent']);
if (isBot) {
const botUrl = generateUrl(req);
fetch(`${renderUrl}/${botUrl}`)
.then(res => res.text())
.then(body => {
res.set('Cache-Control', 'public, max-age=300, s-maxage=600');
res.set('Vary', 'User-Agent');
res.send(body.toString())
});
} else {
fetch(`https://${appUrl}/`)
.then(res => res.text())
.then(body => {
res.send(body.toString());
});
}
});
Is http://pqr.com/render
your personal rendering server? If not, you have to forward the request to https://render-tron.appspot.com/render
or deploy Rendertron separately yourself.
Also right now you just assign the created express-instance to a constant (const app = express('')
), configure it and export it for firebase (which you don't use). Instead you have to run express yourself on a node.js server.
I'm using an Angular 6 app and I was facing the same issue. I did it without using an express server or firebase, instead I used NGINX to check the agent header and route them to rendertron if it's a bot or to the angular app if it's a normal user.
Incase, if you wanted to take this approach using NGINX. Use this configuration.
server {
server_name your-server-name;
root /path to your dist;
index index.html;
location ~ /\. {
deny all;
}
location / {
try_files $uri @prerender;
}
location @prerender {
set $prerender 0;
if ($http_user_agent ~* "googlebot|yahoo|bingbot|baiduspider|yandex|yeti|yodaobot|gigabot|ia_archiver|facebookexternalhit|twitterbot|developers\.google\.com") {
set $prerender 1;
}
if ($args ~ "_escaped_fragment_|prerender=1") {
set $prerender 1;
}
if ($http_user_agent ~ "Prerender") {
set $prerender 0;
}
if ($prerender = 1) {
rewrite .* /render/$scheme://$host$request_uri? break;
proxy_pass https://render-tron.appspot.com; #You can use our own hosted Rendertron
}
if ($prerender = 0) {
rewrite .* /index.html break;
}
}
}
And yes, you can now pre-render if it's a bot.
If you still wanted to do it using a express, rendertron offers an express middleware. You can check it out here.
I found this NGINX configuration from prerender.io, you can find something useful for different server or any other approach in their repo.
来源:https://stackoverflow.com/questions/49360395/server-side-rendering-with-rendertron-angular-5-without-firebase