Skip to content

feat: add SEO meta tags, canonical URLs, and sitemap - #73

Merged
creatorcluster merged 3 commits into
creatorcluster:mainfrom
Coder-soft:main
Aug 8, 2026
Merged

feat: add SEO meta tags, canonical URLs, and sitemap#73
creatorcluster merged 3 commits into
creatorcluster:mainfrom
Coder-soft:main

Conversation

@Coder-soft

Copy link
Copy Markdown

No description provided.

- Generate sitemap.xml at build time and reference it in robots.txt
- Add global Seo component with og/twitter meta tags
- Lazy-load video.js, wavesurfer.js, and generator tabs
- Add dismissible resources announcement banner
- Tighten TypeScript types and fix lint warnings
- add retry UI + failure state to audio/video preview players
- validate svgl, font, texture, and profile API payloads at runtime
- add guide routes to sitemap and make enrichment fetches timeout-safe
- normalize trailing slashes in canonical URLs and fix route name splitting
- point announcement Explore button at the music category
@vercel

vercel Bot commented Aug 8, 2026

Copy link
Copy Markdown

@Coder-soft is attempting to deploy a commit to the yamura3's projects Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Warning

Review limit reached

@Coder-soft, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 8 minutes

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 703b841a-f654-455f-9b89-a334872933b1

📥 Commits

Reviewing files that changed from the base of the PR and between 507128a and ff3c4a2.

⛔ Files ignored due to path filters (4)
  • convex/_generated/api.js is excluded by !**/_generated/**
  • convex/_generated/dataModel.d.ts is excluded by !**/_generated/**
  • convex/_generated/server.d.ts is excluded by !**/_generated/**
  • convex/_generated/server.js is excluded by !**/_generated/**
📒 Files selected for processing (33)
  • convex/dashboard.ts
  • package.json
  • public/robots.txt
  • public/sitemap.xml
  • scripts/export_resources.ts
  • scripts/generate_sitemap.mjs
  • src/App.tsx
  • src/components/AudioPlayer.tsx
  • src/components/FeaturedResources.tsx
  • src/components/InfiniteMenu.tsx
  • src/components/Seo.tsx
  • src/components/VideoPlayer.tsx
  • src/components/admin/AdminCreatorPacksManager.tsx
  • src/components/admin/BlogEditor.tsx
  • src/components/profile/FontPicker.tsx
  • src/components/profile/ImageUpload.tsx
  • src/components/profile/ProfileEditor.tsx
  • src/components/profile/SvglPicker.tsx
  • src/components/resources/ResourceAnnouncementBanner.tsx
  • src/components/resources/ResourceCard.tsx
  • src/hooks/useProfile.ts
  • src/hooks/useUserFavorites.ts
  • src/integrations/supabase/types.d.ts
  • src/lib/showcases.ts
  • src/main.tsx
  • src/pages/BackgroundGenerator.tsx
  • src/pages/BlogView.tsx
  • src/pages/Blogs.tsx
  • src/pages/Generators.tsx
  • src/pages/Profile.tsx
  • src/pages/ResourcesHub.tsx
  • src/pages/Showcase.tsx
  • vite.config.ts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Aug 8, 2026

Copy link
Copy Markdown

Greptile Summary

This change adds shared SEO metadata and generates sitemap entries for public Supabase content. A later failure while retrieving a paginated collection still allows the build to publish a sitemap containing only the earlier pages, leaving later public URLs out of search-engine discovery.

Confidence Score: 4/5

Not safe to merge until dynamic sitemap enrichment handles later-page retrieval failures without publishing incomplete collections.

The sitemap generator completes successfully after a later Supabase page returns an error and serializes only the rows retrieved before that error.

Files Needing Attention: scripts/generate_sitemap.mjs

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced a proof for a posted P1 finding.
  • T-Rex produced a second finding-proof for another posted P1 finding.
  • T-Rex provided a general-contract-validation-proof showing that the sitemap generator returns partial rows for non-OK pages and exits with code 0, meaning it completed and wrote the partial enrichment instead of failing or omitting it.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (1)

  1. General comment

    P1 Later Supabase pagination failure publishes a partial sitemap collection

    • Bug
      • When the second profiles page responds with HTTP 500 after the first page supplied 1,000 records, the generator completes successfully and emits those 1,000 profile URLs in the sitemap. Records beginning with the failed/subsequent page are omitted, yet there is no failure signal preventing publication.
    • Cause
      • fetchJson immediately returns its accumulated rows on !response.ok at scripts/generate_sitemap.mjs:30. The caller then iterates and serializes the returned partial rows at line 52.
    • Fix
      • Treat a non-OK response after pagination has started as an enrichment failure: either throw/fail sitemap generation, or discard that endpoint's accumulated rows and explicitly choose an all-or-nothing fallback. Do not serialize partial paginated results as a complete collection.

    T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "fix: paginate Supabase queries in sitema..." | Re-trigger Greptile

Comment on lines +31 to +35
const [profiles, packs, blogs] = await Promise.all([
fetchJson("profiles?select=username&username=not.is.null"),
fetchJson("creator_packs?select=slug&status=eq.approved"),
fetchJson("blogs?select=slug&published=eq.true"),
]);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Dynamic sitemap generation drops rows above the response cap

Each dynamic Supabase collection is fetched only once. Supabase REST responses can be capped at 1,000 rows, so a successful production build will silently omit public profiles, approved creator packs, and published blogs beyond that first page. Paginate each query with a stable ordering until all pages have been retrieved.

Artifacts

Controlled local sitemap pagination validation script

  • This runnable Node script starts a local Supabase REST mock, invokes the real sitemap generator, records HTTP requests and response status, and counts generated profile URLs; it provides the executable reproduction.

Sitemap generator output with all 1,205 profile rows returned

  • The cap-free controlled run invoked the real generator successfully and recorded one HTTP 200 OK profile request returning and emitting all 1,205 rows; it establishes the complete-response baseline.

Sitemap generator output with a 1,000-row capped profile response

  • The capped controlled run invoked the real generator successfully and recorded one HTTP 200 OK profile request without Range or pagination parameters, returning and emitting only 1,000 of 1,205 rows; it proves the omission.

View artifacts

T-Rex Ran code and verified through T-Rex

- Fetch all rows via Range-based pagination instead of assuming a single page
- Add explicit ordering to profile, pack, and blog queries
@creatorcluster
creatorcluster merged commit 7922770 into creatorcluster:main Aug 8, 2026
2 of 4 checks passed
headers: { ...headers, Range: `${start}-${start + pageSize - 1}`, Prefer: "count=exact" },
signal: controller.signal,
});
if (!response.ok) return rows;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Later-page failures publish an incomplete sitemap

If a paginated Supabase request fails after earlier pages succeeded, this returns the accumulated rows and lets the generator finish normally. The resulting sitemap presents the partial collection as complete, silently omitting all matching URLs from the failed page onward. Propagate the failure or discard the entire collection rather than serializing an incomplete result.

Artifacts

Isolated sitemap pagination failure runtime test source

  • The executable Node test copies the generator to a temporary workdir, mocks a 1,000-row first page and a 500 second page, then asserts the emitted sitemap counts and omissions.

Generated sitemap after second-page Supabase failure

  • The captured successful runtime execution shows both profiles fetch ranges, a sitemap total of 1,026 URLs, 1,000 retained profiles, and absence of profile-1000, proving a partial collection was published.

View artifacts

T-Rex Ran code and verified through T-Rex

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants