fix: improve internal linking for SEO authority distribution#1350
fix: improve internal linking for SEO authority distribution#1350devanshk404 wants to merge 5 commits into
Conversation
- Add hidden breadcrumb nav (sr-only) to listing pages linking back to type hub (/earn/bounties, /earn/projects), sponsor page, and listing title - Make region badge in listing header a clickable link to the region hub page - Fix footer internal links incorrectly opening in new tab (target="_blank") - Convert mobile skills section on listing pages from plain divs to <Link> tags - Fix Date serialization error in grants/[slug] getServerSideProps (Prisma returns Date objects; serialize via JSON.parse/stringify to match string type) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
|
@devanshk404 is attempting to deploy a commit to the Superteam Team on Vercel. A member of the Team first needs to authorize it. |
|
Important Review skippedDraft detected. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
WalkthroughAdds accessible, screen-reader breadcrumb/nav and JSON-LD to multiple earn pages, makes region labels link to region pages when resolvable, converts mobile skill chips into clickable links, conditions external-link attributes in the footer, and JSON-serializes grant objects returned from getServerSideProps. Changes
Sequence Diagram(s)(omitted) Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 2 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/layouts/Listing.tsx`:
- Around line 186-194: The breadcrumb renders a sponsor Link using
initialListing.sponsor.slug but only checks initialListing.sponsor, causing a
bad href if slug is missing; update the conditional around the fragment to
require a valid slug (e.g., initialListing.sponsor &&
initialListing.sponsor.slug) or otherwise render the sponsor name without the
Link, targeting the fragment around the Link/slug usage (initialListing.sponsor,
initialListing.sponsor.slug, and the Link component) so no `/earn/s/undefined`
is produced.
- Around line 234-240: Replace the ad-hoc slugification inside the Link href
(the .toLowerCase().replace(/\s+/g, '-') on the skill variable) with the
project's shared skill slug utility so special names like C++, C#, .NET, Node.js
produce correct routes; import the canonical slug function (e.g., skillSlug or
toSkillSlug) at the top of Listing.tsx and call it in the href:
href={`/earn/skill/${skillSlug(skill)}`} (or the actual utility name), keeping
the Link and key={skill} intact.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5fe94f7d-4607-4975-93f1-4e336c6b38e2
📒 Files selected for processing (5)
src/features/listings/components/ListingPage/RegionLabel.tsxsrc/features/navbar/components/Footer.tsxsrc/layouts/Listing.tsxsrc/pages/earn/grants/[slug]/index.tsxsrc/pages/earn/grants/[slug]/references.tsx
| {initialListing.sponsor && ( | ||
| <> | ||
| <span>/</span> | ||
| <Link | ||
| href={`/earn/s/${initialListing.sponsor.slug}`} | ||
| className="hover:text-slate-600" | ||
| > | ||
| {initialListing.sponsor.name} | ||
| </Link> |
There was a problem hiding this comment.
Guard sponsor breadcrumb link with a slug check.
The current condition only checks initialListing.sponsor, but href depends on initialListing.sponsor.slug. If slug is missing, this renders /earn/s/undefined.
Suggested fix
- {initialListing.sponsor && (
+ {initialListing.sponsor?.slug && initialListing.sponsor?.name && (📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| {initialListing.sponsor && ( | |
| <> | |
| <span>/</span> | |
| <Link | |
| href={`/earn/s/${initialListing.sponsor.slug}`} | |
| className="hover:text-slate-600" | |
| > | |
| {initialListing.sponsor.name} | |
| </Link> | |
| {initialListing.sponsor?.slug && initialListing.sponsor?.name && ( | |
| <> | |
| <span>/</span> | |
| <Link | |
| href={`/earn/s/${initialListing.sponsor.slug}`} | |
| className="hover:text-slate-600" | |
| > | |
| {initialListing.sponsor.name} | |
| </Link> | |
| </> | |
| )} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/layouts/Listing.tsx` around lines 186 - 194, The breadcrumb renders a
sponsor Link using initialListing.sponsor.slug but only checks
initialListing.sponsor, causing a bad href if slug is missing; update the
conditional around the fragment to require a valid slug (e.g.,
initialListing.sponsor && initialListing.sponsor.slug) or otherwise render the
sponsor name without the Link, targeting the fragment around the Link/slug usage
(initialListing.sponsor, initialListing.sponsor.slug, and the Link component) so
no `/earn/s/undefined` is produced.
| <Link | ||
| key={skill} | ||
| href={`/earn/skill/${skill.toLowerCase().replace(/\s+/g, '-')}`} | ||
| className="m-0 rounded-sm bg-slate-100 px-4 py-1 text-xs font-medium text-slate-600 hover:bg-slate-200" | ||
| > | ||
| <p className="text-xs">{skill}</p> | ||
| </div> | ||
| {skill} | ||
| </Link> |
There was a problem hiding this comment.
Use the shared skill slug utility to avoid broken skill routes.
Line 236 uses simplified slugification, which won’t match existing skill route expectations for cases like C++, C#, .NET, or Node.js. This can generate non-resolvable /earn/skill/* links.
Suggested fix
+import { generateSkillSlug } from '@/features/listings/utils/skill';
...
- href={`/earn/skill/${skill.toLowerCase().replace(/\s+/g, '-')}`}
+ href={`/earn/skill/${generateSkillSlug(skill)}`}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Link | |
| key={skill} | |
| href={`/earn/skill/${skill.toLowerCase().replace(/\s+/g, '-')}`} | |
| className="m-0 rounded-sm bg-slate-100 px-4 py-1 text-xs font-medium text-slate-600 hover:bg-slate-200" | |
| > | |
| <p className="text-xs">{skill}</p> | |
| </div> | |
| {skill} | |
| </Link> | |
| <Link | |
| key={skill} | |
| href={`/earn/skill/${generateSkillSlug(skill)}`} | |
| className="m-0 rounded-sm bg-slate-100 px-4 py-1 text-xs font-medium text-slate-600 hover:bg-slate-200" | |
| > | |
| {skill} | |
| </Link> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/layouts/Listing.tsx` around lines 234 - 240, Replace the ad-hoc
slugification inside the Link href (the .toLowerCase().replace(/\s+/g, '-') on
the skill variable) with the project's shared skill slug utility so special
names like C++, C#, .NET, Node.js produce correct routes; import the canonical
slug function (e.g., skillSlug or toSkillSlug) at the top of Listing.tsx and
call it in the href: href={`/earn/skill/${skillSlug(skill)}`} (or the actual
utility name), keeping the Link and key={skill} intact.
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
- Fix /bounties BreadcrumbList position 2 missing item URL - Add BreadcrumbList JSON-LD to /all and /grants (were missing entirely) - Add sr-only breadcrumb nav to /bounties, /all, /grants, /projects - Add sr-only static links block in Default layout for all 21 region hub pages + main listing hubs (footer is ssr:false so Googlebot couldn't see footer links — this block is always in SSR HTML) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Nitpick comments (1)
src/layouts/Default.tsx (1)
57-82: Refactor the static link block into a typed constant + map.The current hardcoded list is easy to desync when regions change. Move these entries into a single source-of-truth constant and render with
.map().Refactor sketch
+const SEO_SITE_LINKS = [ + { href: '/earn/bounties', label: 'Crypto Bounties' }, + { href: '/earn/projects', label: 'Crypto Projects' }, + // ... + { href: '/earn/regions/balkan', label: 'Superteam Balkan' }, +] as const; - <nav aria-label="Site links" className="sr-only" aria-hidden="true"> - <Link href="/earn/bounties" tabIndex={-1}>Crypto Bounties</Link> - ... - </nav> + <nav aria-label="Site links" className="sr-only" aria-hidden="true"> + {SEO_SITE_LINKS.map((link) => ( + <Link key={link.href} href={link.href} tabIndex={-1}> + {link.label} + </Link> + ))} + </nav>🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/layouts/Default.tsx` around lines 57 - 82, Replace the hardcoded <Link> list in Default.tsx with a typed constant array (e.g., export const EARN_LINKS: { href: string; label: string; key?: string }[]) that contains each href/label pair (regions and top-level items) as the single source of truth, then render the nav by mapping EARN_LINKS.map(link => <Link key={link.href || link.key} href={link.href}>{link.label}</Link>) so updates are centralized and strongly typed; ensure you import or define the constant in the same module (or a nearby config file) and preserve existing hrefs/labels exactly.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/layouts/Default.tsx`:
- Around line 56-82: The hidden nav with className="sr-only" is still exposing
many focusable <Link> elements to keyboard users (nav and Link elements in
Default.tsx), so update the block to remove it from the accessibility tree and
tab order: add aria-hidden="true" to the <nav> (or role="presentation" +
aria-hidden) and ensure each <Link> inside is non-focusable (tabIndex={-1} or
render as inert) or set aria-hidden on the links themselves so they cannot be
tabbed into; keep the links only for SEO/crawlers while preventing keyboard
focus and screen-reader exposure.
In `@src/pages/earn/bounties/index.tsx`:
- Around line 38-42: The breadcrumb nav currently exposes the "/" separator to
screen readers and leaves the current page as a link; update the markup so the
separator span has aria-hidden="true" (or role="presentation") and replace the
final Link for the current page with non-link text that has aria-current="page"
(e.g., <span aria-current="page">Crypto Bounties</span>), applying the same
changes to the corresponding breadcrumb blocks in the other pages that repeat
this pattern.
---
Nitpick comments:
In `@src/layouts/Default.tsx`:
- Around line 57-82: Replace the hardcoded <Link> list in Default.tsx with a
typed constant array (e.g., export const EARN_LINKS: { href: string; label:
string; key?: string }[]) that contains each href/label pair (regions and
top-level items) as the single source of truth, then render the nav by mapping
EARN_LINKS.map(link => <Link key={link.href || link.key}
href={link.href}>{link.label}</Link>) so updates are centralized and strongly
typed; ensure you import or define the constant in the same module (or a nearby
config file) and preserve existing hrefs/labels exactly.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 7e60a2eb-1fae-425b-8eac-c99ee1c72ee3
📒 Files selected for processing (5)
src/layouts/Default.tsxsrc/pages/earn/all/index.tsxsrc/pages/earn/bounties/index.tsxsrc/pages/earn/grants/index.tsxsrc/pages/earn/projects/index.tsx
✅ Files skipped from review due to trivial changes (1)
- src/pages/earn/projects/index.tsx
| <nav aria-label="Site links" className="sr-only"> | ||
| <Link href="/earn/bounties">Crypto Bounties</Link> | ||
| <Link href="/earn/projects">Crypto Projects</Link> | ||
| <Link href="/earn/grants">Crypto Grants</Link> | ||
| <Link href="/earn/all">All Opportunities</Link> | ||
| <Link href="/earn/regions/india">Superteam India</Link> | ||
| <Link href="/earn/regions/nigeria">Superteam Nigeria</Link> | ||
| <Link href="/earn/regions/brazil">Superteam Brazil</Link> | ||
| <Link href="/earn/regions/germany">Superteam Germany</Link> | ||
| <Link href="/earn/regions/united-states">Superteam United States</Link> | ||
| <Link href="/earn/regions/uk">Superteam UK</Link> | ||
| <Link href="/earn/regions/ukraine">Superteam Ukraine</Link> | ||
| <Link href="/earn/regions/singapore">Superteam Singapore</Link> | ||
| <Link href="/earn/regions/malaysia">Superteam Malaysia</Link> | ||
| <Link href="/earn/regions/indonesia">Superteam Indonesia</Link> | ||
| <Link href="/earn/regions/uae">Superteam UAE</Link> | ||
| <Link href="/earn/regions/spain">Superteam Spain</Link> | ||
| <Link href="/earn/regions/netherlands">Superteam Netherlands</Link> | ||
| <Link href="/earn/regions/canada">Superteam Canada</Link> | ||
| <Link href="/earn/regions/japan">Superteam Japan</Link> | ||
| <Link href="/earn/regions/poland">Superteam Poland</Link> | ||
| <Link href="/earn/regions/korea">Superteam Korea</Link> | ||
| <Link href="/earn/regions/ireland">Superteam Ireland</Link> | ||
| <Link href="/earn/regions/kazakhstan">Superteam Kazakhstan</Link> | ||
| <Link href="/earn/regions/georgia">Superteam Georgia</Link> | ||
| <Link href="/earn/regions/balkan">Superteam Balkan</Link> | ||
| </nav> |
There was a problem hiding this comment.
Avoid invisible keyboard focus targets in the sr-only SEO links block.
At Line 56, this nav is visually hidden but all links remain focusable, which can trap keyboard users on non-visible elements. If this block is SEO-only, remove it from the accessibility tree and tab order.
Safe SEO-only variant
- <nav aria-label="Site links" className="sr-only">
+ <nav aria-label="Site links" className="sr-only" aria-hidden="true">
- <Link href="/earn/bounties">Crypto Bounties</Link>
+ <Link href="/earn/bounties" tabIndex={-1}>Crypto Bounties</Link>
- <Link href="/earn/projects">Crypto Projects</Link>
+ <Link href="/earn/projects" tabIndex={-1}>Crypto Projects</Link>
...
- <Link href="/earn/regions/balkan">Superteam Balkan</Link>
+ <Link href="/earn/regions/balkan" tabIndex={-1}>Superteam Balkan</Link>
</nav>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <nav aria-label="Site links" className="sr-only"> | |
| <Link href="/earn/bounties">Crypto Bounties</Link> | |
| <Link href="/earn/projects">Crypto Projects</Link> | |
| <Link href="/earn/grants">Crypto Grants</Link> | |
| <Link href="/earn/all">All Opportunities</Link> | |
| <Link href="/earn/regions/india">Superteam India</Link> | |
| <Link href="/earn/regions/nigeria">Superteam Nigeria</Link> | |
| <Link href="/earn/regions/brazil">Superteam Brazil</Link> | |
| <Link href="/earn/regions/germany">Superteam Germany</Link> | |
| <Link href="/earn/regions/united-states">Superteam United States</Link> | |
| <Link href="/earn/regions/uk">Superteam UK</Link> | |
| <Link href="/earn/regions/ukraine">Superteam Ukraine</Link> | |
| <Link href="/earn/regions/singapore">Superteam Singapore</Link> | |
| <Link href="/earn/regions/malaysia">Superteam Malaysia</Link> | |
| <Link href="/earn/regions/indonesia">Superteam Indonesia</Link> | |
| <Link href="/earn/regions/uae">Superteam UAE</Link> | |
| <Link href="/earn/regions/spain">Superteam Spain</Link> | |
| <Link href="/earn/regions/netherlands">Superteam Netherlands</Link> | |
| <Link href="/earn/regions/canada">Superteam Canada</Link> | |
| <Link href="/earn/regions/japan">Superteam Japan</Link> | |
| <Link href="/earn/regions/poland">Superteam Poland</Link> | |
| <Link href="/earn/regions/korea">Superteam Korea</Link> | |
| <Link href="/earn/regions/ireland">Superteam Ireland</Link> | |
| <Link href="/earn/regions/kazakhstan">Superteam Kazakhstan</Link> | |
| <Link href="/earn/regions/georgia">Superteam Georgia</Link> | |
| <Link href="/earn/regions/balkan">Superteam Balkan</Link> | |
| </nav> | |
| <nav aria-label="Site links" className="sr-only" aria-hidden="true"> | |
| <Link href="/earn/bounties" tabIndex={-1}>Crypto Bounties</Link> | |
| <Link href="/earn/projects" tabIndex={-1}>Crypto Projects</Link> | |
| <Link href="/earn/grants" tabIndex={-1}>Crypto Grants</Link> | |
| <Link href="/earn/all" tabIndex={-1}>All Opportunities</Link> | |
| <Link href="/earn/regions/india" tabIndex={-1}>Superteam India</Link> | |
| <Link href="/earn/regions/nigeria" tabIndex={-1}>Superteam Nigeria</Link> | |
| <Link href="/earn/regions/brazil" tabIndex={-1}>Superteam Brazil</Link> | |
| <Link href="/earn/regions/germany" tabIndex={-1}>Superteam Germany</Link> | |
| <Link href="/earn/regions/united-states" tabIndex={-1}>Superteam United States</Link> | |
| <Link href="/earn/regions/uk" tabIndex={-1}>Superteam UK</Link> | |
| <Link href="/earn/regions/ukraine" tabIndex={-1}>Superteam Ukraine</Link> | |
| <Link href="/earn/regions/singapore" tabIndex={-1}>Superteam Singapore</Link> | |
| <Link href="/earn/regions/malaysia" tabIndex={-1}>Superteam Malaysia</Link> | |
| <Link href="/earn/regions/indonesia" tabIndex={-1}>Superteam Indonesia</Link> | |
| <Link href="/earn/regions/uae" tabIndex={-1}>Superteam UAE</Link> | |
| <Link href="/earn/regions/spain" tabIndex={-1}>Superteam Spain</Link> | |
| <Link href="/earn/regions/netherlands" tabIndex={-1}>Superteam Netherlands</Link> | |
| <Link href="/earn/regions/canada" tabIndex={-1}>Superteam Canada</Link> | |
| <Link href="/earn/regions/japan" tabIndex={-1}>Superteam Japan</Link> | |
| <Link href="/earn/regions/poland" tabIndex={-1}>Superteam Poland</Link> | |
| <Link href="/earn/regions/korea" tabIndex={-1}>Superteam Korea</Link> | |
| <Link href="/earn/regions/ireland" tabIndex={-1}>Superteam Ireland</Link> | |
| <Link href="/earn/regions/kazakhstan" tabIndex={-1}>Superteam Kazakhstan</Link> | |
| <Link href="/earn/regions/georgia" tabIndex={-1}>Superteam Georgia</Link> | |
| <Link href="/earn/regions/balkan" tabIndex={-1}>Superteam Balkan</Link> | |
| </nav> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/layouts/Default.tsx` around lines 56 - 82, The hidden nav with
className="sr-only" is still exposing many focusable <Link> elements to keyboard
users (nav and Link elements in Default.tsx), so update the block to remove it
from the accessibility tree and tab order: add aria-hidden="true" to the <nav>
(or role="presentation" + aria-hidden) and ensure each <Link> inside is
non-focusable (tabIndex={-1} or render as inert) or set aria-hidden on the links
themselves so they cannot be tabbed into; keep the links only for SEO/crawlers
while preventing keyboard focus and screen-reader exposure.
| <nav aria-label="Breadcrumb" className="sr-only"> | ||
| <Link href="/earn">Home</Link> | ||
| <span>/</span> | ||
| <Link href="/earn/bounties">Crypto Bounties</Link> | ||
| </nav> |
There was a problem hiding this comment.
Tighten breadcrumb semantics for assistive tech.
At Line 40, the / separator should be hidden from screen readers, and at Line 41 the current page item should be marked as current (typically non-link text). This same pattern repeats in src/pages/earn/all/index.tsx (Lines 39-43) and src/pages/earn/grants/index.tsx (Lines 46-50).
Suggested markup adjustment
- <nav aria-label="Breadcrumb" className="sr-only">
- <Link href="/earn">Home</Link>
- <span>/</span>
- <Link href="/earn/bounties">Crypto Bounties</Link>
- </nav>
+ <nav aria-label="Breadcrumb" className="sr-only">
+ <ol>
+ <li><Link href="/earn">Home</Link></li>
+ <li aria-hidden="true">/</li>
+ <li aria-current="page">Crypto Bounties</li>
+ </ol>
+ </nav>📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <nav aria-label="Breadcrumb" className="sr-only"> | |
| <Link href="/earn">Home</Link> | |
| <span>/</span> | |
| <Link href="/earn/bounties">Crypto Bounties</Link> | |
| </nav> | |
| <nav aria-label="Breadcrumb" className="sr-only"> | |
| <ol> | |
| <li><Link href="/earn">Home</Link></li> | |
| <li aria-hidden="true">/</li> | |
| <li aria-current="page">Crypto Bounties</li> | |
| </ol> | |
| </nav> |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@src/pages/earn/bounties/index.tsx` around lines 38 - 42, The breadcrumb nav
currently exposes the "/" separator to screen readers and leaves the current
page as a link; update the markup so the separator span has aria-hidden="true"
(or role="presentation") and replace the final Link for the current page with
non-link text that has aria-current="page" (e.g., <span
aria-current="page">Crypto Bounties</span>), applying the same changes to the
corresponding breadcrumb blocks in the other pages that repeat this pattern.
…atch Placing the nav after Footer (ssr:false) caused React to see it as an unexpected element during client hydration due to dynamic import tree shifting. Moving it before the footer keeps its position stable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
| <Link href="/earn/regions/india">Superteam India</Link> | ||
| <Link href="/earn/regions/nigeria">Superteam Nigeria</Link> | ||
| <Link href="/earn/regions/brazil">Superteam Brazil</Link> | ||
| <Link href="/earn/regions/germany">Superteam Germany</Link> | ||
| <Link href="/earn/regions/united-states">Superteam United States</Link> | ||
| <Link href="/earn/regions/uk">Superteam UK</Link> | ||
| <Link href="/earn/regions/ukraine">Superteam Ukraine</Link> | ||
| <Link href="/earn/regions/singapore">Superteam Singapore</Link> | ||
| <Link href="/earn/regions/malaysia">Superteam Malaysia</Link> | ||
| <Link href="/earn/regions/indonesia">Superteam Indonesia</Link> | ||
| <Link href="/earn/regions/uae">Superteam UAE</Link> | ||
| <Link href="/earn/regions/spain">Superteam Spain</Link> | ||
| <Link href="/earn/regions/netherlands">Superteam Netherlands</Link> |
There was a problem hiding this comment.
Fetch these regions from prisma.chapters and dynamically create this map instead of having to manually update this everytime a new chapter is added
| return { | ||
| props: { | ||
| grant: grantData, | ||
| grant: JSON.parse(JSON.stringify(grantData)), |
There was a problem hiding this comment.
better to .map and change date fields in there instead of doing this hacky way
| return { | ||
| props: { | ||
| grant: grantData, | ||
| grant: JSON.parse(JSON.stringify(grantData)), |
- Replace hardcoded chapter links in Default.tsx with dynamic useQuery fetch - Replace JSON.parse/stringify in grants slug pages with explicit date mapping - Fix nested <a> in ListingCard by converting sponsor link to span with router.push - Fix undefined serialization error for icons/link fields in homepage chapters Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Resolve ListingCard conflict: keep useRouter, drop useTokenLookup (replaced by TokenIcon on main) - Update grants slug pages: remove redundant toISOString calls since getGrantBySlug now serializes dates - Fix next.config.ts type assertion for browserToTerminal (not yet in Next.js 16.1.6 types) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Summary
sr-only) to every listing page — links back to the type hub (/earn/bounties,/earn/projects), sponsor page, and listing title. Invisible to users, crawlable by Google<Link>to the region hub page (e.g./earn/regions/india) — every regional listing now links back to its hub<div>tags to<Link>tags pointing to skill pagestarget="_blank"(Bounties, Projects, Grants, Categories were opening in a new tab)Dateserialization error ingrants/[slug]getServerSideProps— Prisma returnsDateobjects which Next.js can't serialize; fixed withJSON.parse(JSON.stringify(...))to match the existingstringtype expectationContext
Part of an internal linking SEO audit. The goal is to distribute ranking authority from strong pages into key Earn hubs (bounties, projects, grants, region pages, skill pages). Without consistent internal links pointing to these hubs, Google treats them as weakly connected and crawls them less frequently.
Footer regions column was explored but deferred — the Footer has
ssr: falsein Default.tsx so any links added there won't be in the initial HTML.Test plan
aria-label="Breadcrumb"withsr-onlyclass)/earn/regions/hub/earn/grants/[slug]) — should load without the Date serialization error🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes