Compare commits

...

2 commits

Author SHA1 Message Date
Chris Parsons
8e73296067 Fix robots.txt and sitemap issues from code review
All checks were successful
🚀 Deploy / 🧪 Test (pull_request) Successful in 1m32s
🚀 Deploy / ʦ TypeScript (pull_request) Successful in 1m23s
🚀 Deploy / 🔍 Lint (pull_request) Successful in 49s
🚀 Deploy / 🐳 Build (pull_request) Has been skipped
🚀 Deploy / 🚀 Deploy (pull_request) Has been skipped
- Point Sitemap directive at /sitemap.xml (not .gz) so crawlers receive
  plain XML without needing Content-Encoding headers
- Add Disallow: /leagues/ to block all auth-gated league routes
- Gitignore public/sitemap.xml* so they are always generated fresh at
  build time rather than serving a stale committed snapshot

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 22:16:49 -07:00
Chris Parsons
2978ba787d Add robots.txt and sitemap.xml.gz for SEO
Adds a static robots.txt blocking admin/API/auth routes, a sitemap
generation script (scripts/generate-sitemap.mjs) that writes both
sitemap.xml and sitemap.xml.gz to public/, and hooks it into the
build so the sitemap is always fresh on deploy.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-24 22:05:37 -07:00
4 changed files with 57 additions and 1 deletions

4
.gitignore vendored
View file

@ -24,3 +24,7 @@ storybook-static
# Clerk migration export — contains password hashes, never commit
exported_users.csv
# Generated at build time by scripts/generate-sitemap.mjs
/public/sitemap.xml
/public/sitemap.xml.gz

View file

@ -3,8 +3,9 @@
"private": true,
"type": "module",
"scripts": {
"build": "npm run build:remix && npm run build:server",
"build": "npm run sitemap && npm run build:remix && npm run build:server",
"build:remix": "react-router build",
"sitemap": "node scripts/generate-sitemap.mjs",
"build:server": "node scripts/build-server.mjs",
"db:generate": "dotenv -- drizzle-kit generate",
"db:migrate": "dotenv -- drizzle-kit migrate",

11
public/robots.txt Normal file
View file

@ -0,0 +1,11 @@
User-agent: *
Allow: /
Disallow: /admin/
Disallow: /api/
Disallow: /leagues/
Disallow: /onboarding
Disallow: /settings
Disallow: /user-profile
Sitemap: https://brackt.com/sitemap.xml

View file

@ -0,0 +1,40 @@
import { gzipSync } from "zlib";
import { writeFileSync } from "fs";
import { join, dirname } from "path";
import { fileURLToPath } from "url";
const __dirname = dirname(fileURLToPath(import.meta.url));
const publicDir = join(__dirname, "..", "public");
const BASE_URL = "https://brackt.com";
const urls = [
{ loc: "/", changefreq: "weekly", priority: "1.0" },
{ loc: "/how-to-play", changefreq: "monthly", priority: "0.8" },
{ loc: "/rules", changefreq: "monthly", priority: "0.8" },
{ loc: "/sports", changefreq: "weekly", priority: "0.8" },
{ loc: "/support", changefreq: "monthly", priority: "0.6" },
{ loc: "/privacy-policy", changefreq: "yearly", priority: "0.4" },
];
const today = new Date().toISOString().split("T")[0];
const xml = `<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
${urls
.map(
({ loc, changefreq, priority }) => ` <url>
<loc>${BASE_URL}${loc}</loc>
<lastmod>${today}</lastmod>
<changefreq>${changefreq}</changefreq>
<priority>${priority}</priority>
</url>`
)
.join("\n")}
</urlset>
`;
writeFileSync(join(publicDir, "sitemap.xml"), xml);
writeFileSync(join(publicDir, "sitemap.xml.gz"), gzipSync(xml));
console.log(`Sitemap generated: ${urls.length} URLs`);