SEO: local AV/DC targeting, static service + case-study pages
- services-data.js: 4 service landing pages (commercial AV install DC,
broadcast integration, LED/XR, conference room AV) with FAQ + areas
- build-pages.mjs: node-stdlib generator -> /services/<slug>/,
/projects/<slug>/, index pages, sitemap.xml; Service/FAQPage/Article/
BreadcrumbList JSON-LD on every page
- index.html: title/description/OG retargeted to 'Commercial AV &
Broadcast Systems Integrator - Washington, DC'; ProfessionalService
schema gains geo, areaServed (DMV cities), hasOfferCatalog; noscript
fallback links the new pages
- components.jsx: hero copy + footer links point at real service pages
- nginx.conf/Dockerfile: ship generated pages, robots/sitemap types
- llms.txt: service pages + service area
2026-09-18 08:00:19 -04:00
#!/usr/bin/env node
// Renders crawlable static pages from services-data.js + projects-data.js:
// /services/index.html, /services/<slug>/index.html, /projects/index.html,
// /projects/<slug>/index.html, plus sitemap.xml. Node stdlib only.
import fs from "node:fs" ;
import path from "node:path" ;
import vm from "node:vm" ;
const ROOT = path . dirname ( new URL ( import . meta . url ) . pathname ) ;
const SITE = "https://wilddragon.net" ;
const TODAY = new Date ( ) . toISOString ( ) . slice ( 0 , 10 ) ;
const win = { _ _R : ( p ) => "/" + p } ;
vm . runInNewContext ( fs . readFileSync ( path . join ( ROOT , "projects-data.js" ) , "utf8" ) , { window : win , _ _R : win . _ _R } ) ;
vm . runInNewContext ( fs . readFileSync ( path . join ( ROOT , "services-data.js" ) , "utf8" ) , { window : win } ) ;
2026-09-18 16:02:18 -04:00
const { PROJECTS , SERVICE _PAGES , SERVICE _AREAS , LOCATION _PAGES } = win ;
SEO: local AV/DC targeting, static service + case-study pages
- services-data.js: 4 service landing pages (commercial AV install DC,
broadcast integration, LED/XR, conference room AV) with FAQ + areas
- build-pages.mjs: node-stdlib generator -> /services/<slug>/,
/projects/<slug>/, index pages, sitemap.xml; Service/FAQPage/Article/
BreadcrumbList JSON-LD on every page
- index.html: title/description/OG retargeted to 'Commercial AV &
Broadcast Systems Integrator - Washington, DC'; ProfessionalService
schema gains geo, areaServed (DMV cities), hasOfferCatalog; noscript
fallback links the new pages
- components.jsx: hero copy + footer links point at real service pages
- nginx.conf/Dockerfile: ship generated pages, robots/sitemap types
- llms.txt: service pages + service area
2026-09-18 08:00:19 -04:00
const esc = ( s ) => String ( s ) . replace ( /[&<>"]/g , ( c ) => ( { "&" : "&" , "<" : "<" , ">" : ">" , '"' : """ } [ c ] ) ) ;
const abs = ( p ) => ( p . startsWith ( "http" ) ? p : SITE + ( p . startsWith ( "/" ) ? p : "/" + p ) ) ;
const write = ( rel , html ) => {
const f = path . join ( ROOT , rel ) ;
fs . mkdirSync ( path . dirname ( f ) , { recursive : true } ) ;
fs . writeFileSync ( f , html ) ;
} ;
const NAV = ` <header class="sp-nav"><div class="container sp-nav-inner">
< a class = "sp-brand" href = "/" > < img src = "/images/dragon-mark.png" alt = "" width = "28" height = "28" / > < span > Wild Dragon < / s p a n > < / a >
< nav aria - label = "Primary" > < a href = "/services/" > Services < / a > < a h r e f = " / p r o j e c t s / " > P r o j e c t s < / a > < a h r e f = " / # a b o u t " > A b o u t < / a > < a h r e f = " m a i l t o : z g a e t a n o @ w i l d d r a g o n . n e t " > C o n t a c t < / a > < / n a v >
< / d i v > < / h e a d e r > ` ;
const FOOTER = ` <footer class="footer"><div class="container">
< div class = "footer-top" >
< div > < div class = "footer-brand" > < img src = "/images/dragon-mark.png" alt = "Wild Dragon" / > < span > Wild Dragon < / s p a n > < / d i v >
< p class = "about-line" > Broadcast systems and commercial AV design , integration , and commissioning — Washington , DC and the DMV . < / p > < / d i v >
< div class = "footer-col" > < h4 > Services < / h 4 > < u l > $ { S E R V I C E _ P A G E S . m a p ( ( s ) = > ` < l i > < a h r e f = " / s e r v i c e s / $ { s . s l u g } / " > $ { e s c ( s . t i t l e ) } < / a > < / l i > ` ) . j o i n ( " " ) } < / u l > < / d i v >
2026-09-18 16:02:18 -04:00
< div class = "footer-col" > < h4 > Service Areas < /h4><ul>${LOCATION_PAGES.map((l) => `<li><a href="/ $ { l . slug } / ">${esc(l.title)}</a></li>`).join(" " ) } < / u l > < / d i v >
SEO: local AV/DC targeting, static service + case-study pages
- services-data.js: 4 service landing pages (commercial AV install DC,
broadcast integration, LED/XR, conference room AV) with FAQ + areas
- build-pages.mjs: node-stdlib generator -> /services/<slug>/,
/projects/<slug>/, index pages, sitemap.xml; Service/FAQPage/Article/
BreadcrumbList JSON-LD on every page
- index.html: title/description/OG retargeted to 'Commercial AV &
Broadcast Systems Integrator - Washington, DC'; ProfessionalService
schema gains geo, areaServed (DMV cities), hasOfferCatalog; noscript
fallback links the new pages
- components.jsx: hero copy + footer links point at real service pages
- nginx.conf/Dockerfile: ship generated pages, robots/sitemap types
- llms.txt: service pages + service area
2026-09-18 08:00:19 -04:00
< div class = "footer-col" > < h4 > Projects < / h 4 > < u l > $ { P R O J E C T S . m a p ( ( p ) = > ` < l i > < a h r e f = " / p r o j e c t s / $ { p . s l u g } / " > $ { e s c ( p . c l i e n t ) } < / a > < / l i > ` ) . j o i n ( " " ) } < / u l > < / d i v >
< / d i v >
< div class = "footer-bottom" > < span > © $ { new Date ( ) . getFullYear ( ) } Zachary Gaetano · Wild Dragon < / s p a n > < s p a n > W a s h i n g t o n , D C < / s p a n > < / d i v >
< / d i v > < / f o o t e r > ` ;
// ponytail: page-local CSS instead of touching styles.css — the SPA never renders these pages.
const STYLE = ` <style>
. sp - nav { background : var ( -- color - primary ) ; padding : 1.1 rem 0 } . sp - nav - inner { display : flex ; align - items : center ; justify - content : space - between }
. sp - brand { display : flex ; align - items : center ; gap : . 6 rem ; color : # fff ; font - family : var ( -- font - mono ) ; font - size : . 8 rem ; letter - spacing : . 18 em ; text - transform : uppercase } . sp - brand img { filter : brightness ( 0 ) invert ( 1 ) }
. sp - nav nav { display : flex ; gap : 1.5 rem } . sp - nav nav a { color : rgba ( 255 , 255 , 255 , . 75 ) ; font - size : . 8 rem ; font - weight : 500 } . sp - nav nav a : hover { color : var ( -- color - accent ) }
. sp - hero { background : var ( -- color - primary ) ; color : # fff ; padding : 4.5 rem 0 4 rem ; position : relative ; overflow : hidden }
. sp - hero img { position : absolute ; inset : 0 ; width : 100 % ; height : 100 % ; object - fit : cover ; opacity : . 22 } . sp - hero . container { position : relative }
. sp - hero h1 { font - family : var ( -- font - display ) ; font - size : clamp ( 2 rem , 4.4 vw , 3.25 rem ) ; font - weight : 600 ; line - height : 1.05 ; letter - spacing : - . 02 em ; margin : 0 0 1.25 rem ; max - width : 52 rem }
. sp - hero . lede { color : rgba ( 255 , 255 , 255 , . 72 ) ; font - size : 1.125 rem ; line - height : 1.7 ; max - width : 44 rem }
. sp - main { padding : 4 rem 0 5 rem } . sp - prose { max - width : 52 rem ; color : var ( -- color - muted ) ; line - height : 1.8 ; font - size : 1.0625 rem } . sp - prose p { margin : 0 0 1.25 rem }
. sp - grid { display : grid ; grid - template - columns : repeat ( auto - fit , minmax ( 16 rem , 1 fr ) ) ; gap : 1.25 rem ; margin : 2.5 rem 0 }
. sp - card { border : 1 px solid var ( -- neutral - 200 , # e5e5e5 ) ; border - radius : . 75 rem ; padding : 1.5 rem } . sp - card h3 { margin : 0 0 . 5 rem ; font - size : 1 rem } . sp - card p { margin : 0 ; color : var ( -- color - muted ) ; font - size : . 95 rem ; line - height : 1.6 }
. sp - h2 { font - family : var ( -- font - display ) ; font - size : 1.6 rem ; font - weight : 600 ; letter - spacing : - . 01 em ; margin : 3 rem 0 1 rem }
. sp - faq dt { font - weight : 600 ; margin - top : 1.25 rem } . sp - faq dd { margin : . 35 rem 0 0 ; color : var ( -- color - muted ) ; line - height : 1.7 }
. sp - tags { display : flex ; flex - wrap : wrap ; gap : . 5 rem ; margin : 1 rem 0 } . sp - tags span { font - family : var ( -- font - mono ) ; font - size : . 7 rem ; letter - spacing : . 08 em ; border : 1 px solid var ( -- neutral - 200 , # e5e5e5 ) ; border - radius : 999 px ; padding : . 3 rem . 7 rem ; color : var ( -- color - muted ) }
. sp - areas { color : var ( -- color - muted ) ; font - size : . 95 rem } . sp - cta { margin - top : 3 rem }
ul . sp - list { padding - left : 1.25 rem ; color : var ( -- color - muted ) ; line - height : 1.8 }
. sp - related { display : grid ; grid - template - columns : repeat ( auto - fit , minmax ( 14 rem , 1 fr ) ) ; gap : 1 rem } . sp - related a { display : block ; border : 1 px solid var ( -- neutral - 200 , # e5e5e5 ) ; border - radius : . 75 rem ; padding : 1.25 rem ; color : var ( -- color - primary ) } . sp - related a : hover { border - color : var ( -- color - accent ) }
. sp - related small { display : block ; color : var ( -- color - muted ) ; margin - top : . 35 rem }
@ media ( max - width : 640 px ) { . sp - nav nav { gap : 1 rem } . sp - nav nav a : nth - child ( 3 ) { display : none } }
< / s t y l e > ` ;
function page ( { url , title , description , image , ld , body , breadcrumb } ) {
const crumbs = { "@type" : "BreadcrumbList" , itemListElement : breadcrumb . map ( ( [ name , item ] , i ) => ( { "@type" : "ListItem" , position : i + 1 , name , item : abs ( item ) } ) ) } ;
return ` <!doctype html>
< html lang = "en" >
< head >
< meta charset = "utf-8" / >
< meta name = "viewport" content = "width=device-width, initial-scale=1" / >
< title > $ { esc ( title ) } < / t i t l e >
< meta name = "description" content = "${esc(description)}" / >
< meta name = "robots" content = "index, follow, max-snippet:-1, max-image-preview:large" / >
< meta name = "geo.region" content = "US-DC" / > < meta name = "geo.placename" content = "Washington, DC" / >
< link rel = "canonical" href = "${abs(url)}" / >
< meta property = "og:type" content = "website" / > < meta property = "og:site_name" content = "Wild Dragon" / > < meta property = "og:locale" content = "en_US" / >
< meta property = "og:url" content = "${abs(url)}" / > < meta property = "og:title" content = "${esc(title)}" / >
< meta property = "og:description" content = "${esc(description)}" / > < meta property = "og:image" content = "${abs(image)}" / >
< meta name = "twitter:card" content = "summary_large_image" / > < meta name = "twitter:title" content = "${esc(title)}" / > < meta name = "twitter:description" content = "${esc(description)}" / > < meta name = "twitter:image" content = "${abs(image)}" / >
< meta name = "theme-color" content = "#0a0a0a" / >
< link rel = "icon" href = "/images/dragon-mark.png" type = "image/png" / >
< link rel = "preconnect" href = "https://fonts.googleapis.com" > < link rel = "preconnect" href = "https://fonts.gstatic.com" crossorigin >
< link href = "https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&family=JetBrains+Mono:wght@400;500&display=swap" rel = "stylesheet" >
< link rel = "stylesheet" href = "/styles.css" >
< style > : root { -- font - inter : "Inter" ; -- font - mono - stack : "JetBrains Mono" } < / s t y l e >
$ { STYLE }
< script type = "application/ld+json" > $ { JSON . stringify ( { "@context" : "https://schema.org" , "@graph" : [ ... ld , crumbs ] } ) } < / s c r i p t >
< / h e a d >
< body >
$ { NAV }
$ { body }
$ { FOOTER }
< / b o d y >
< / h t m l >
` ;
}
const BUSINESS _ID = SITE + "/#organization" ;
const projectCard = ( p ) => ` <a href="/projects/ ${ p . slug } /"><strong> ${ esc ( p . client ) } </strong><small> ${ esc ( p . title ) } </small></a> ` ;
// ── service pages ──────────────────────────────────────────────────────────
for ( const s of SERVICE _PAGES ) {
const url = ` /services/ ${ s . slug } / ` ;
const related = s . related . map ( ( slug ) => PROJECTS . find ( ( p ) => p . slug === slug ) ) . filter ( Boolean ) ;
const ld = [
{ "@type" : "Service" , "@id" : abs ( url ) + "#service" , name : s . title , description : s . metaDescription , url : abs ( url ) ,
provider : { "@id" : BUSINESS _ID } , areaServed : SERVICE _AREAS . map ( ( n ) => ( { "@type" : "Place" , name : n } ) ) , serviceType : s . title ,
hasOfferCatalog : { "@type" : "OfferCatalog" , name : s . title , itemListElement : s . services . map ( ( [ n , d ] ) => ( { "@type" : "Offer" , itemOffered : { "@type" : "Service" , name : n , description : d } } ) ) } } ,
{ "@type" : "FAQPage" , mainEntity : s . faq . map ( ( [ q , a ] ) => ( { "@type" : "Question" , name : q , acceptedAnswer : { "@type" : "Answer" , text : a } } ) ) } ,
] ;
const body = `
< section class = "sp-hero" > < img src = "/${s.hero}" alt = "" loading = "eager" fetchpriority = "high" / > < div class = "container" >
< div class = "eyebrow" > $ { esc ( s . eyebrow ) } < / d i v > < h 1 > $ { e s c ( s . t i t l e ) } < / h 1 > < p c l a s s = " l e d e " > $ { e s c ( s . l e d e ) } < / p >
< p style = "margin-top:2rem" > < a class = "btn btn-primary" href = "mailto:zgaetano@wilddragon.net?subject=${encodeURIComponent(s.title)}" > Request a consultation < / a > < / p >
< / d i v > < / s e c t i o n >
< main class = "sp-main" > < div class = "container" >
< div class = "sp-prose" > $ { s . body . map ( ( p ) => ` <p> ${ esc ( p ) } </p> ` ) . join ( "" ) } < / d i v >
< h2 class = "sp-h2" > What ' s included < / h 2 >
< div class = "sp-grid" > $ { s . services . map ( ( [ n , d ] ) => ` <div class="sp-card"><h3> ${ esc ( n ) } </h3><p> ${ esc ( d ) } </p></div> ` ) . join ( "" ) } < / d i v >
< h2 class = "sp-h2" > Service area < / h 2 >
< p class = "sp-areas" > $ { SERVICE _AREAS . map ( esc ) . join ( " · " ) } < / p >
2026-09-18 16:02:18 -04:00
< p class = "sp-areas" > $ { LOCATION _PAGES . map ( ( l ) => ` <a href="/ ${ l . slug } /"> ${ esc ( l . title ) } </a> ` ) . join ( " · " ) } < / p >
SEO: local AV/DC targeting, static service + case-study pages
- services-data.js: 4 service landing pages (commercial AV install DC,
broadcast integration, LED/XR, conference room AV) with FAQ + areas
- build-pages.mjs: node-stdlib generator -> /services/<slug>/,
/projects/<slug>/, index pages, sitemap.xml; Service/FAQPage/Article/
BreadcrumbList JSON-LD on every page
- index.html: title/description/OG retargeted to 'Commercial AV &
Broadcast Systems Integrator - Washington, DC'; ProfessionalService
schema gains geo, areaServed (DMV cities), hasOfferCatalog; noscript
fallback links the new pages
- components.jsx: hero copy + footer links point at real service pages
- nginx.conf/Dockerfile: ship generated pages, robots/sitemap types
- llms.txt: service pages + service area
2026-09-18 08:00:19 -04:00
< h2 class = "sp-h2" > Frequently asked questions < / h 2 >
< dl class = "sp-faq" > $ { s . faq . map ( ( [ q , a ] ) => ` <dt> ${ esc ( q ) } </dt><dd> ${ esc ( a ) } </dd> ` ) . join ( "" ) } < / d l >
$ { related . length ? ` <h2 class="sp-h2">Related projects</h2><div class="sp-related"> ${ related . map ( projectCard ) . join ( "" ) } </div> ` : "" }
< div class = "sp-cta" > < a class = "btn btn-primary" href = "mailto:zgaetano@wilddragon.net?subject=${encodeURIComponent(s.title)}" > Request a consultation < / a > < / d i v >
< / d i v > < / m a i n > ` ;
write ( url + "index.html" , page ( { url , title : s . metaTitle , description : s . metaDescription , image : s . hero , ld , body , breadcrumb : [ [ "Home" , "/" ] , [ "Services" , "/services/" ] , [ s . title , url ] ] } ) ) ;
}
// ── project pages ──────────────────────────────────────────────────────────
for ( const p of PROJECTS ) {
const url = ` /projects/ ${ p . slug } / ` ;
const desc = p . summary . length > 158 ? p . summary . slice ( 0 , 155 ) . replace ( /\s+\S*$/ , "" ) + "…" : p . summary ;
const ld = [ { "@type" : "Article" , "@id" : abs ( url ) + "#article" , headline : p . title , description : p . summary , image : abs ( p . thumbnail ) , url : abs ( url ) ,
author : { "@id" : SITE + "/#person" } , publisher : { "@id" : BUSINESS _ID } , about : { "@type" : "Organization" , name : p . client } , keywords : [ p . category , ... ( p . technologies || [ ] ) ] . join ( ", " ) } ] ;
const body = `
< section class = "sp-hero" > < img src = "${p.thumbnail}" alt = "${esc(p.title)}" loading = "eager" fetchpriority = "high" / > < div class = "container" >
< div class = "eyebrow" > $ { esc ( p . category ) } · $ { esc ( p . year ) } < / d i v > < h 1 > $ { e s c ( p . t i t l e ) } < / h 1 > < p c l a s s = " l e d e " > $ { e s c ( p . s u m m a r y ) } < / p >
< / d i v > < / s e c t i o n >
< main class = "sp-main" > < div class = "container" >
< div class = "sp-prose" > $ { p . description . map ( ( t ) => ` <p> ${ esc ( t ) } </p> ` ) . join ( "" ) } < / d i v >
$ { p . highlights ? ` <h2 class="sp-h2">Highlights</h2><ul class="sp-list"> ${ p . highlights . map ( ( h ) => ` <li> ${ esc ( h ) } </li> ` ) . join ( "" ) } </ul> ` : "" }
$ { p . scope ? ` <h2 class="sp-h2">Scope</h2><div class="sp-tags"> ${ p . scope . map ( ( t ) => ` <span> ${ esc ( t ) } </span> ` ) . join ( "" ) } </div> ` : "" }
$ { p . technologies ? ` <h2 class="sp-h2">Technologies</h2><div class="sp-tags"> ${ p . technologies . map ( ( t ) => ` <span> ${ esc ( t ) } </span> ` ) . join ( "" ) } </div> ` : "" }
< div class = "sp-cta" > < a class = "btn btn-primary" href = "/#/projects/${p.slug}" > Open interactive case study < / a > < / d i v >
< / d i v > < / m a i n > ` ;
write ( url + "index.html" , page ( { url , title : ` ${ p . title } | Case Study | Wild Dragon ` , description : desc , image : p . thumbnail , ld , body , breadcrumb : [ [ "Home" , "/" ] , [ "Projects" , "/projects/" ] , [ p . title , url ] ] } ) ) ;
}
// ── index pages ────────────────────────────────────────────────────────────
write ( "services/index.html" , page ( { url : "/services/" , title : "AV & Broadcast Integration Services | Washington DC | Wild Dragon" ,
description : "Commercial AV installation, broadcast systems integration, LED video walls, and conference room AV — designed, installed, and commissioned in Washington, DC and the DMV." ,
image : "images/wild-dragon-logo.jpg" , ld : [ ] , breadcrumb : [ [ "Home" , "/" ] , [ "Services" , "/services/" ] ] ,
body : ` <section class="sp-hero"><div class="container"><div class="eyebrow">Services · Washington, DC</div><h1>AV & broadcast integration services</h1><p class="lede">Design, installation, and commissioning for commercial AV and broadcast facilities across the DMV.</p></div></section>
< main class = "sp-main" > < div class = "container" > < div class = "sp-related" > $ { SERVICE _PAGES . map ( ( s ) => ` <a href="/services/ ${ s . slug } /"><strong> ${ esc ( s . title ) } </strong><small> ${ esc ( s . lede ) } </small></a> ` ) . join ( "" ) } < / d i v > < / d i v > < / m a i n > ` } ) ) ;
write ( "projects/index.html" , page ( { url : "/projects/" , title : "Broadcast & AV Integration Case Studies | Wild Dragon" ,
description : "Case studies: broadcast facilities, cloud production, XR stages, and AV integration for the Washington Commanders, BetMGM, CVS/Aetna, UBS, Monumental Sports, Intuit, and Red Sands." ,
image : "images/photos/production-switcher.jpg" , ld : [ ] , breadcrumb : [ [ "Home" , "/" ] , [ "Projects" , "/projects/" ] ] ,
body : ` <section class="sp-hero"><div class="container"><div class="eyebrow">Selected work</div><h1>Case studies</h1><p class="lede">Facilities designed, integrated, and commissioned by Wild Dragon.</p></div></section>
< main class = "sp-main" > < div class = "container" > < div class = "sp-related" > $ { PROJECTS . map ( projectCard ) . join ( "" ) } < / d i v > < / d i v > < / m a i n > ` } ) ) ;
2026-09-18 16:02:18 -04:00
// ── location / keyword pages ───────────────────────────────────────────────
for ( const l of LOCATION _PAGES ) {
const url = ` / ${ l . slug } / ` ;
const svcs = l . services . map ( ( slug ) => SERVICE _PAGES . find ( ( s ) => s . slug === slug ) ) . filter ( Boolean ) ;
const related = l . related . map ( ( slug ) => PROJECTS . find ( ( p ) => p . slug === slug ) ) . filter ( Boolean ) ;
const ld = [
{ "@type" : "Service" , "@id" : abs ( url ) + "#service" , name : l . title , description : l . metaDescription , url : abs ( url ) ,
provider : { "@id" : BUSINESS _ID } , areaServed : SERVICE _AREAS . map ( ( n ) => ( { "@type" : "Place" , name : n } ) ) , serviceType : l . title } ,
{ "@type" : "FAQPage" , mainEntity : l . faq . map ( ( [ q , a ] ) => ( { "@type" : "Question" , name : q , acceptedAnswer : { "@type" : "Answer" , text : a } } ) ) } ,
] ;
const body = `
< section class = "sp-hero" > < img src = "/${l.hero}" alt = "" loading = "eager" fetchpriority = "high" / > < div class = "container" >
< div class = "eyebrow" > $ { esc ( l . eyebrow ) } < / d i v > < h 1 > $ { e s c ( l . t i t l e ) } < / h 1 > < p c l a s s = " l e d e " > $ { e s c ( l . l e d e ) } < / p >
< p style = "margin-top:2rem" > < a class = "btn btn-primary" href = "mailto:zgaetano@wilddragon.net?subject=${encodeURIComponent(l.title)}" > Request a consultation < / a > < / p >
< / d i v > < / s e c t i o n >
< main class = "sp-main" > < div class = "container" >
< div class = "sp-prose" > $ { l . body . map ( ( p ) => ` <p> ${ esc ( p ) } </p> ` ) . join ( "" ) } < / d i v >
< h2 class = "sp-h2" > Services < / h 2 >
< div class = "sp-related" > $ { svcs . map ( ( s ) => ` <a href="/services/ ${ s . slug } /"><strong> ${ esc ( s . title ) } </strong><small> ${ esc ( s . lede ) } </small></a> ` ) . join ( "" ) } < / d i v >
< h2 class = "sp-h2" > Service area < / h 2 >
< p class = "sp-areas" > $ { SERVICE _AREAS . map ( esc ) . join ( " · " ) } < / p >
< h2 class = "sp-h2" > Frequently asked questions < / h 2 >
2026-09-22 07:44:15 -04:00
$ { l . subpages ? ` <p class="sp-areas">See also: ${ l . subpages . map ( ( sl ) => LOCATION _PAGES . find ( ( x ) => x . slug === sl ) ) . filter ( Boolean ) . map ( ( x ) => ` <a href="/ ${ x . slug } /"> ${ esc ( x . title ) } </a> ` ) . join ( " · " ) } </p> ` : "" }
2026-09-18 16:02:18 -04:00
< dl class = "sp-faq" > $ { l . faq . map ( ( [ q , a ] ) => ` <dt> ${ esc ( q ) } </dt><dd> ${ esc ( a ) } </dd> ` ) . join ( "" ) } < / d l >
$ { related . length ? ` <h2 class="sp-h2">Related projects</h2><div class="sp-related"> ${ related . map ( projectCard ) . join ( "" ) } </div> ` : "" }
< div class = "sp-cta" > < a class = "btn btn-primary" href = "mailto:zgaetano@wilddragon.net?subject=${encodeURIComponent(l.title)}" > Request a consultation < / a > < / d i v >
< / d i v > < / m a i n > ` ;
write ( url + "index.html" , page ( { url , title : l . metaTitle , description : l . metaDescription , image : l . hero , ld , body , breadcrumb : [ [ "Home" , "/" ] , [ l . title , url ] ] } ) ) ;
}
SEO: local AV/DC targeting, static service + case-study pages
- services-data.js: 4 service landing pages (commercial AV install DC,
broadcast integration, LED/XR, conference room AV) with FAQ + areas
- build-pages.mjs: node-stdlib generator -> /services/<slug>/,
/projects/<slug>/, index pages, sitemap.xml; Service/FAQPage/Article/
BreadcrumbList JSON-LD on every page
- index.html: title/description/OG retargeted to 'Commercial AV &
Broadcast Systems Integrator - Washington, DC'; ProfessionalService
schema gains geo, areaServed (DMV cities), hasOfferCatalog; noscript
fallback links the new pages
- components.jsx: hero copy + footer links point at real service pages
- nginx.conf/Dockerfile: ship generated pages, robots/sitemap types
- llms.txt: service pages + service area
2026-09-18 08:00:19 -04:00
// ── sitemap ────────────────────────────────────────────────────────────────
2026-09-18 16:02:18 -04:00
const urls = [ [ "/" , "1.0" ] , [ "/services/" , "0.9" ] , ... SERVICE _PAGES . map ( ( s ) => [ ` /services/ ${ s . slug } / ` , "0.9" ] ) , ... LOCATION _PAGES . map ( ( l ) => [ ` / ${ l . slug } / ` , "0.9" ] ) , [ "/projects/" , "0.7" ] , ... PROJECTS . map ( ( p ) => [ ` /projects/ ${ p . slug } / ` , "0.7" ] ) ] ;
SEO: local AV/DC targeting, static service + case-study pages
- services-data.js: 4 service landing pages (commercial AV install DC,
broadcast integration, LED/XR, conference room AV) with FAQ + areas
- build-pages.mjs: node-stdlib generator -> /services/<slug>/,
/projects/<slug>/, index pages, sitemap.xml; Service/FAQPage/Article/
BreadcrumbList JSON-LD on every page
- index.html: title/description/OG retargeted to 'Commercial AV &
Broadcast Systems Integrator - Washington, DC'; ProfessionalService
schema gains geo, areaServed (DMV cities), hasOfferCatalog; noscript
fallback links the new pages
- components.jsx: hero copy + footer links point at real service pages
- nginx.conf/Dockerfile: ship generated pages, robots/sitemap types
- llms.txt: service pages + service area
2026-09-18 08:00:19 -04:00
write ( "sitemap.xml" , ` <?xml version="1.0" encoding="UTF-8"?>
< urlset xmlns = "http://www.sitemaps.org/schemas/sitemap/0.9" >
$ { urls . map ( ( [ u , pr ] ) => ` <url><loc> ${ abs ( u ) } </loc><lastmod> ${ TODAY } </lastmod><priority> ${ pr } </priority></url> ` ) . join ( "\n" ) }
< / u r l s e t >
` );
2026-09-18 16:02:18 -04:00
console . log ( ` built ${ SERVICE _PAGES . length } service + ${ LOCATION _PAGES . length } location + ${ PROJECTS . length } project pages, sitemap ${ urls . length } urls ` ) ;