DEV Community

Amanda Jayathilaka
Amanda Jayathilaka

Posted on

Programmatic Pages: Generate a Static Directory Site from JSON with Node.js

Turn one JSON file into hundreds of static HTML pages and a sitemap using a small Node.js script.

Directories are a perfect fit for static generation. One data file, one template, hundreds of fast pages. No framework needed.

This is the same idea behind a branch directory I run for Chase Bank locations.

Project layout

data/branches.json
build.js
dist/
Enter fullscreen mode Exit fullscreen mode

The data

[
  { "slug": "dallas", "name": "Chase Bank, Dallas", "area": "LBJ and Abrams", "phone": "972-690-8600" },
  { "slug": "katy", "name": "Chase Bank, Katy", "area": "Fry and Morton", "phone": "281-646-6600" }
]
Enter fullscreen mode Exit fullscreen mode

The build script

import { readFileSync, writeFileSync, mkdirSync } from "node:fs";

const SITE = "https://example.com";
const branches = JSON.parse(readFileSync("data/branches.json", "utf8"));

const esc = (s) =>
  s.replace(/[&<>"']/g, (c) => ({ "&": "&amp;", "<": "&lt;", ">": "&gt;", '"': "&quot;", "'": "&#39;" }[c]));

const page = (b) => `<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>${esc(b.name)} | Phone Number and Location</title>
  <meta name="description" content="Find the location and phone number for ${esc(b.name)}.">
  <link rel="canonical" href="${SITE}/${b.slug}/">
</head>
<body>
  <h1>${esc(b.name)}</h1>
  <p>${esc(b.area)}</p>
  <p><a href="tel:${b.phone.replace(/\D/g, "")}">${esc(b.phone)}</a></p>
</body>
</html>`;

mkdirSync("dist", { recursive: true });

for (const b of branches) {
  mkdirSync(`dist/${b.slug}`, { recursive: true });
  writeFileSync(`dist/${b.slug}/index.html`, page(b));
}

const sitemap = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${branches.map((b) => `  <url><loc>${SITE}/${b.slug}/</loc></url>`).join("\n")}
</urlset>`;

writeFileSync("dist/sitemap.xml", sitemap);
console.log(`Built ${branches.length} pages`);
Enter fullscreen mode Exit fullscreen mode

Run it with node build.js.

Avoid thin content

Programmatic SEO fails when every page says the same thing with the city name swapped. Add something genuinely useful per page: real hours, nearby branches, services, or a map.

Next steps

  • Add a unique meta description per page.
  • Add JSON-LD structured data.
  • Submit the sitemap in Google Search Console.

Top comments (0)