Skip to content

Commit c0a6a4d

Browse files
authored
Restore sitemap after reorg (#35)
1 parent 336a8f2 commit c0a6a4d

File tree

2 files changed

+117
-0
lines changed

2 files changed

+117
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ This cross-platform script will:
4141
4. Build the TypeDoc documentation for each repository
4242
5. Copy the documentation to a central `docs` folder
4343
6. Create a main index.html file that allows navigation between the different API references
44+
7. Generate a combined sitemap.xml that includes URLs from all repositories for better SEO
4445

4546
> [!NOTE]
4647
> The build script automatically cleans and recreates the `repos` directory each time it's run, ensuring you always get a fresh build with the latest code from the configured branches.

build.mjs

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,118 @@ function copyDirContents(src, dest) {
9696
}
9797
}
9898

99+
/**
100+
* Combine sitemap.xml files from all repositories
101+
*/
102+
function combineSitemaps() {
103+
const sitemaps = [];
104+
let siteUrl = 'https://api.playcanvas.com';
105+
106+
// Check the package.json for homepage URL
107+
try {
108+
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'));
109+
if (packageJson.homepage) {
110+
siteUrl = packageJson.homepage;
111+
}
112+
} catch (error) {
113+
console.warn('Warning: Could not read package.json to determine site URL.');
114+
}
115+
116+
// Remove trailing slash if present
117+
siteUrl = siteUrl.replace(/\/$/, '');
118+
119+
console.log(`Using site URL: ${siteUrl}`);
120+
121+
// Collect URLs from each repository's sitemap
122+
for (const repo of REPOS) {
123+
const sitemapPath = path.join('docs', repo.name, 'sitemap.xml');
124+
if (fs.existsSync(sitemapPath)) {
125+
try {
126+
const sitemapContent = fs.readFileSync(sitemapPath, 'utf8');
127+
console.log(`Processing sitemap for ${repo.name} (${sitemapPath})`);
128+
129+
// Extract URLs and lastmod times using regex
130+
const urlRegex = /<url>[\s\S]*?<loc>(.*?)<\/loc>(?:[\s\S]*?<lastmod>(.*?)<\/lastmod>)?[\s\S]*?<\/url>/g;
131+
let match;
132+
let count = 0;
133+
134+
while ((match = urlRegex.exec(sitemapContent)) !== null) {
135+
let url = match[1];
136+
const lastmod = match[2] || '';
137+
let finalUrl = '';
138+
139+
// Make relative to site root if needed
140+
if (url.startsWith('http')) {
141+
// Extract the path portion from the URL
142+
const urlPath = new URL(url).pathname;
143+
144+
// Remove leading slash for consistency in checks
145+
const normalizedPath = urlPath.replace(/^\//, '');
146+
const normalizedRepoName = repo.name.replace(/^\//, '').replace(/\/$/, '');
147+
148+
// Check if the path already includes the repo name to avoid duplication
149+
if (normalizedPath.startsWith(`${normalizedRepoName}/`)) {
150+
finalUrl = `${siteUrl}${urlPath}`;
151+
} else {
152+
finalUrl = `${siteUrl}/${normalizedRepoName}/${normalizedPath}`;
153+
}
154+
} else {
155+
// For relative URLs, normalize paths
156+
const normalizedUrl = url.replace(/^\//, '');
157+
const normalizedRepoName = repo.name.replace(/^\//, '').replace(/\/$/, '');
158+
159+
// Check if the URL already starts with the repo name
160+
if (normalizedUrl.startsWith(`${normalizedRepoName}/`)) {
161+
finalUrl = `${siteUrl}/${normalizedUrl}`;
162+
} else {
163+
finalUrl = `${siteUrl}/${normalizedRepoName}/${normalizedUrl}`;
164+
}
165+
}
166+
167+
let urlEntry = `
168+
<url>
169+
<loc>${finalUrl}</loc>`;
170+
171+
// Add lastmod if available
172+
if (lastmod) {
173+
urlEntry += `
174+
<lastmod>${lastmod}</lastmod>`;
175+
}
176+
177+
urlEntry += `
178+
</url>`;
179+
180+
sitemaps.push(urlEntry);
181+
count++;
182+
}
183+
184+
console.log(`Extracted ${count} URLs from ${repo.name} sitemap`);
185+
} catch (error) {
186+
console.warn(`Warning: Could not process sitemap for ${repo.name}: ${error.message}`);
187+
}
188+
} else {
189+
console.warn(`Warning: No sitemap found for ${repo.name}`);
190+
}
191+
}
192+
193+
// Add root page to sitemap with current date as lastmod
194+
const today = new Date().toISOString().split('T')[0];
195+
sitemaps.unshift(`
196+
<url>
197+
<loc>${siteUrl}/</loc>
198+
<lastmod>${today}</lastmod>
199+
</url>`);
200+
201+
// Create combined sitemap
202+
const combinedSitemap = `<?xml version="1.0" encoding="UTF-8"?>
203+
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">${sitemaps.join('')}
204+
</urlset>`;
205+
206+
// Write to the docs folder
207+
fs.writeFileSync(path.join('docs', 'sitemap.xml'), combinedSitemap);
208+
console.log(`Combined sitemap created successfully with ${sitemaps.length} URLs.`);
209+
}
210+
99211
/**
100212
* Main function to build the documentation
101213
*/
@@ -164,6 +276,10 @@ async function buildDocs() {
164276
copyDirContents('assets', path.join('docs', 'assets'));
165277
}
166278

279+
// Generate combined sitemap
280+
console.log('\nGenerating combined sitemap...');
281+
combineSitemaps();
282+
167283
console.log('\nDocumentation build complete. Run "npm run serve" to view it.');
168284
} catch (error) {
169285
console.error(`\nError: ${error.message}`);

0 commit comments

Comments
 (0)