Skip to content

Commit

Permalink
Merge pull request #191 from htdangkhoa/develop
Browse files Browse the repository at this point in the history
  • Loading branch information
htdangkhoa committed Dec 14, 2021
2 parents c31725a + b0d699f commit 254d871
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 141 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,12 @@
"glob": "^7.2.0",
"husky": "^7.0.4",
"identity-obj-proxy": "^3.0.0",
"jest": "^27.4.4",
"jest": "^27.4.5",
"lint-staged": "^12.1.2",
"mini-css-extract-plugin": "^2.4.5",
"nock": "^13.2.1",
"picocolors": "^1.0.0",
"plop": "^3.0.4",
"plop": "^3.0.5",
"postcss": "^8.4.5",
"postcss-loader": "^6.2.1",
"prettier": "^2.5.1",
Expand Down
7 changes: 6 additions & 1 deletion src/server/render/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,19 @@ import configurationStore from 'client/store';
import routes from 'client/routes';

import renderHtml from './render-html';
import sitemapGenerator from './sitemap-generator';

const renderController = async (req, res) => {
const store = configurationStore();

const contexts = [];

const loadBranchData = () => {
const promises = matchRoutes(routes, req.path).map(({ route, params }) => {
const routesMatch = matchRoutes(routes, req.path);

sitemapGenerator(req, routesMatch);

const promises = routesMatch.map(({ route, params }) => {
// handling redirects in react-router v6
// reference: https://gist.github.com/htdangkhoa/5b3407c749b6fb8cf05cfb591ec3ef07#handling-redirects-in-react-router-v6
if (typeof route.to === 'string') {
Expand Down
74 changes: 74 additions & 0 deletions src/server/render/sitemap-generator.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import fs from 'fs';
import path from 'path';

/**
* @param {string} xml
*/
const formatXml = (xml) => {
let s = xml;

// Create the padding element
const spaces = ' '.repeat(2);

// Regex to match xml tags.
const attrib = '\\s*\\w+(?:\\s*=\\s*(?:\\w+|"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"))?';
const anyTag = new RegExp(`(<\\/?\\w+(?:${attrib})*\\s*\\/?>)`, 'g');

// Split into 'clean' new lines.
s = s
.split(anyTag)
.map((line) => line.trim())
.filter((line) => line !== '')
.map((line) => line.split(/\r?\n|\r/));

let pad = 0;
// 'flatten' the array.
return []
.concat(...s)
.map((line) => {
if (line[0] === '<' && line[1] === '/') pad -= 1;
const out = spaces.repeat(pad) + line;
if (line[0] === '<' && line[1] !== '/') pad += 1;

return out;
})
.join('\n');
};

/**
* @param {import('pure-http').IRequest} req
* @param {any[]} routesMatch
*/
const sitemapGenerator = (req, routesMatch = []) => {
const baseUrl = [`${req.protocol}://`, req.hostname, ![80, 443].includes(req.port) && `:${req.port}`]
.filter(Boolean)
.join('');

const urls = routesMatch.map(({ pathname }, i) => {
let s = `<url>\n<loc>${baseUrl}${pathname}</loc>\n</url>`;

if (i !== routesMatch.length - 1) {
s += '\n';
}

return s;
});

let beautyXml = '<?xml version="1.0" encoding="UTF-8"?>\n';

const template = `
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls.join('')}
</urlset>
`;

beautyXml += formatXml(template);

const sitemapPath = path.resolve(process.cwd(), 'public/sitemap.xml');

fs.writeFileSync(sitemapPath, beautyXml, 'utf8');

return beautyXml;
};

export default sitemapGenerator;
Loading

0 comments on commit 254d871

Please sign in to comment.