Repository navigation
feat: website overhaul — content, SEO/AEO, AI-discoverability, i18n - #211
Merged
Merged
Conversation
- /changelog: Timeline of releases with markdown rendering, fetched from GitHub API during build - /showcase: Company logos, industry tags, testimonials from engineers - /community: Discord, GitHub, Reddit, Twitter, LinkedIn cards with contributing section - /examples: 17 examples with tag filtering, featured section - Header nav: Docs, Changelog, Examples, Community - Footer: Added links to all new pages - Mobile nav: Site-wide links added - Search: Improved ranking with word-boundary matching, keyboard hints - CLI page: Replaced "Coming Soon" with install instructions and links - Releases: Redirects to /changelog - Pkg pages: Show redirect to relevant docs instead of blank - SEO: robots.txt, comprehensive sitemap - New components: SectionCards, Tabs, PkgRedirect - Markdoc: Registered tabs and section-cards tags Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Substantial revamp of gofr.dev focused on three things: (1) telling
visitors what GoFr does before showing who uses it, (2) making the
site machine-readable for AI search engines and coding assistants,
and (3) replacing static copy with build-time data pulled from the
framework repo so the site stays current without hand-edits.
Content
-------
- New SEO pages, all rendered through existing Markdoc chrome:
/why-gofr — narrative pitch grounded in the framework's
own positioning ("opinionated microservice
framework, Kubernetes-first, observability
built in").
/comparison — pillar with feature matrix; per-framework
deep dives at /comparison/gofr-vs-{gin,
fiber,echo,chi}. Each acknowledges the
competing framework's strengths so the
tone stays honest, not adversarial.
/migrate — index + concrete code translations for
/migrate/from-{gin,fiber,express,flask,
spring-boot}.
/learn — three tracks (switchers / Go devs new to
GoFr / production builders), each just an
ordered list of links into existing docs.
/faq — long-tail Q&A grouped by topic (pricing,
features, datasources, observability,
comparison, deployment, testing). Audited
for accuracy: removed unverifiable production-
readiness claims, fixed CockroachDB / ClickHouse
mis-categorisation, removed Go version mismatch.
/team — auto-generated from src/data/team.json and
enriched live from GitHub (avatars, location,
contributor count). 4 maintainers + 130
contributors at time of writing.
/roadmap — milestones pulled from GitHub at build time.
/showcase, /examples, /community, /events, /changelog — refreshed
existing pages with metadata, RSS, dynamic
content where applicable.
- Home page restructured for substance-first reading:
Hero → feature grid → datasource marquee → company logos →
ecosystem recognition → testimonials. Pitch first, then prove.
- New EcosystemRecognition strip surfaces ThoughtWorks Tech Radar
(Languages & Frameworks), CNCF Landscape (App Definition &
Development), and JetBrains Open Source program — neutral
credibility signals to complement the existing customer logos.
- Hero copy refined: tighter subhead, latest-release badge from
changelog data, AI-coding-assistant tertiary line pointing at
/AGENTS.md (real, shipped) for visitors building with Claude Code,
Cursor, Codex, or Aider.
- Removed: ZopSmart references throughout (footer, showcase,
CompanyTrustedList, FAQ, GFGTracks); the standalone Calendly
CTA in the hero; the "block our calendar" tertiary; the AGENTS.md
callout banner that duplicated the hero's inline link; the
copyright/license footer line; the standalone "A note on
benchmarks" section in /comparison; the /benchmarks page (kept
for a future revisit when there are real numbers to publish).
SEO / AEO infrastructure
------------------------
- Per-page Markdoc frontmatter (nextjs.metadata.title / description)
on every doc + SEO page so Google + AI Overviews see unique,
intent-matched titles instead of inheriting from layout.
- New Markdoc tags for AI-search optimisation:
{% answer %} — direct-answer block at the top of a doc, the
kind LLMs quote.
{% faq %} +
{% faq-item %} — collapsible Q/A block; emits FAQPage JSON-LD.
{% howto %} — numbered steps; emits HowTo JSON-LD.
- Dynamic sitemap at /sitemap.xml — walks src/app/**/page.{md,jsx}
via fast-glob at build time; replaces the previous static file
(deleted) so newly added pages appear automatically.
- Twitter / OpenGraph metadata blocks on every layout that owns a
route group (faq, comparison, migrate, learn, examples, etc.).
- robots.txt + .well-known/security.txt + humans.txt added.
For AI coding assistants and search engines
-------------------------------------------
- /AGENTS.md — curated context file at the well-known root path.
10 core rules an assistant must respect, a minimal app, a tight
Migrations section (rules + pointer rather than inlined examples
to save tokens), and a categorised "where to look" link index.
Linked inline from the hero for visitors using Claude Code /
Cursor / Aider / Codex / Continue.
- /llms.txt — Markdown-shaped curated link index per the emerging
llmstxt.org spec. Sectioned (Quick Start / Advanced Guide /
Datasources / References / Comparison and migration / Examples
and showcase / Project / For AI assistants) so AI engines can
partial-fetch.
- Footer: replaced the duplicate "For AI assistants" entry with
"LLM index" → /llms.txt. Top-of-page + bottom-of-page placement
matches the audience split: AGENTS.md is for the developer
wiring up an assistant (hero), llms.txt is for the AI crawler
(footer).
Build-time data fetchers
------------------------
- utils/fetch-releases.mjs — GitHub releases → src/app/changelog/releases.json
- utils/fetch-roadmap.mjs — GitHub milestones → src/data/roadmap.json
- utils/fetch-team.mjs — Team + contributors → src/data/team-enriched.json
- utils/generate-changelog-rss.mjs — public/changelog.xml (RSS)
Each fetcher has an offline-tolerant snapshot fallback so a
rate-limited or offline build keeps the previously-fetched JSON
rather than silently emptying it.
Build hooks adjusted: the GitHub fetchers no longer run on every
build (they hit GitHub rate limits and slowed local dev). They now
run only via `npm run refresh-data`; only the (local-only) RSS
generator runs on `prebuild`. JSON snapshots are committed and
update on demand or on release.
i18n / localisation
-------------------
- Spanish (/es/*) and Simplified Chinese (/zh/*) variants of the
hero, with LocaleAutoRedirect picking the user's preferred
language on first visit (and storing a manual override so the
user's later choice sticks).
- Footer language switcher.
- hreflang annotations on the root layout.
Components added
----------------
- MarketingPage — chrome wrapper for SEO pages (no left
sidebar, right rail TOC kept).
- LatestReleaseBadge — small inline version chip in the hero
fed from releases.json.
- LocaleAutoRedirect — browser-language sniffing on /.
- EcosystemRecognition — TW Radar / CNCF / JetBrains row with
per-source metadata.
- Faq + FaqSearchProvider — client-side search across FAQ items.
- Answer / HowTo — Markdoc tag renderers.
Changelog / RSS
---------------
- changelog page: full release history (108 releases) with deep-
link anchors per version (/changelog#v1.56.0 auto-expands).
- RSS feed at /changelog.xml regenerated from releases.json.
CSS fixes
---------
- prism.css: removed the global `code { background-color }` rule
that was painting per-line "pill" backgrounds on every `<code>`
inside `<pre>`. Scoped to `:not(pre) > code`.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Both have been active contributors to gofr-dev/gofr (verified via the framework's commit history). LinkedIn URLs supplied directly; GitHub handles confirmed via the noreply.github.com address pattern in their commits. team-enriched.json regenerated against the live GitHub API: 6 core members + 128 community contributors (total 134; the two new maintainers move out of the community contributor list, keeping the total stable). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
team page - Card stripped to identity essentials: avatar, name, role, location, GitHub + LinkedIn. Removed bio, company, blog, and the stats row (commits/repos/followers) — every card now has identical structure so the grid reads as one set of people, not six different layouts. - Spacer (`flex-1` + `h-full`) removed; cards size to content rather than forcing a tall uniform height with dead air above the footer. - Sort: Creator pinned first, then Maintainers ordered by commit count to gofr-dev/gofr (highest first). Source order in team.json is left alone so this is purely a render-time sort. - New section between maintainer cards and the contributor wall: Top contributors (top 5 community devs by commit count). Visual hierarchy steps maintainers (72px avatar) → top contributors (64px, with login + commit count) → contributor wall (40px avatar dots). team-enriched / fetch-team - Cross-reference contributors API to stash each core member's commit count under github_data.gofr_contributions. Field is harmless when not rendered; powers the sort and the future-proofing in case we ever want to surface it again. changelog - Client-side pagination, 20 releases per page. Initial render emits all release data into the DOM (so deep-link anchors keep working) but only the first chunk is visible. "Show 20 older" advances the window in PAGE_SIZE chunks; "Showing X of Y" status line. - Right rail now powered by `allGroups` (from full release list) instead of the visible window — every month is one click away. Click handler auto-extends `shown` to include the target month before scrolling, so an older month from the rail just works. - Deep-link auto-expand fixed: a hash like /changelog#v1.30.0 that points past the current pagination window now extends `shown` to include the target before scrolling. - ReleaseCard hydration mismatch fixed: `hashMatch` was being computed at render time from `window.location.hash`, which differs server vs client. Moved to a useEffect that runs after hydration. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
changelog
- Body now groups by minor-version line (v1.56, v1.55, …) instead of
by month. Section headers use mono / no .x suffix per feedback. Each
release card keeps its date inline as metadata, so chronology is
visible without being the sort axis.
- Right rail is a flat list of every exact release ("v1.56.4 · Apr 29
'24"). Year shown as compact apostrophe form so the rail row stays
narrow but spans-multiple-years isn't ambiguous.
- Click → jumps to that release; auto-extends pagination if it sits
past the visible window. Active row is set by a release-tag scroll-
spy so the rail tracks position as you scroll.
- Removed the by-month / by-version tab toggle — version-only navi-
gation reads cleaner.
SEO / AI discoverability
- src/app/layout.jsx: <link rel="alternate"> tags for /llms.txt
(text/plain) and /AGENTS.md (text/markdown), plus the emerging
rel="llm" and rel="ai-context" hints. Crawlers that follow rel-
alternate pick up both files automatically.
- public/robots.txt: explicit comment annotations referencing both
AI files, so a human auditing the site's crawler policy sees them
without having to crawl every link.
- src/app/sitemap.js: /llms.txt and /AGENTS.md added as STATIC_ROUTES
with priority 0.9 so they appear in /sitemap.xml as first-class
indexable URLs.
showcase
- CTA reframed: "Add your company to the showcase" → "Share a
testimonial". The issue prefill template now asks for Name / Role
/ Happy to be quoted publicly instead of Company name / Industry.
Better fit for the audience that actually adopts GoFr (individual
developers) versus pushing contributors to get corporate sign-off.
home page
- Fixed silent click-trap: the decorative blur-orb <Image> in the
feature grid was absolute + opacity-25 + mt-80 with no pointer-
events setting, so it floated above the DBlist / ecosystem cards /
testimonials below and swallowed their clicks. Added
pointer-events-none.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Six research agents spanning llms.txt adoption, AGENTS.md convention, AI engine citation patterns, traditional Google SEO, community/social traffic for OSS frameworks, and crawler/bot directives converged on a small set of evidence-backed wins. Hyped surfaces (heavy schema stacking, llms.txt as a crawler signal, OG cards as direct AI signal) were dropped. sitemap.js - Drop <changefreq> and <priority>: Google explicitly ignores both. - Compute per-route <lastmod> from `git log -1 --format=%cI` of the source page file (fs mtime fallback when git is unavailable). Honest "last actually edited" beats build-time on every URL — Google trains on the signal and discounts sitemaps that bump every URL on every build. - Add /llms.txt, /AGENTS.md, /robots.txt as static-file entries so they're discoverable from the sitemap too. src/app/layout.jsx - Site-wide <meta name="robots"> with max-snippet:-1, max-image-preview:large, max-video-preview:-1 — required to be quoted in full by AI Overviews and to surface large image previews in SERP cards. Restrictive-wins-on-conflict makes this the safe default. public/robots.txt - Explicit allow-list per canonical 2025-26 AI/answer bot user- agent (OpenAI: GPTBot/OAI-SearchBot/ChatGPT-User; Anthropic: ClaudeBot/Claude-SearchBot/Claude-User; Google: Googlebot/ Google-Extended; Bing, Perplexity, Apple, Meta, Cohere, You, DuckAssist, Amazon). User-agent: * already permits everything; per-bot stanzas make the policy unambiguous to crawler operators. - Comment annotations pointing humans at /AGENTS.md and /llms.txt. src/components/DocStructuredData.jsx (new) - Per-doc TechArticle + BreadcrumbList JSON-LD. Client component so Next 14 static export pre-renders the <script type="application/ ld+json"> tags into the HTML payload that crawlers read; usePathname() resolves at build time, not runtime, for static routes. src/components/LastUpdatedByline.jsx + utils/generate-doc-mtimes.mjs + src/data/doc-mtimes.json (new) - Small visible "Last updated <date>" line under each doc title. Date comes from a per-route map regenerated at prebuild from git log of the source file. Reasoning: Dec 2025 Google core update rewarded freshness — winners averaged 393 days since last update vs. losers' 500 days (Amsive analysis). Visible byline + accurate sitemap lastmod = real freshness signal both surfaces. - Hooked into npm prebuild and refresh-data scripts. DocsLayout.jsx - Wires DocStructuredData (in head) + LastUpdatedByline (under title) on every doc page. No change to other layouts. What was deliberately not added (research said no): - llms.txt as anything beyond a manual-paste DX surface (~0.1% of AI-bot requests touch it; Google's John Mueller: "no AI system currently uses llms.txt"; SE Ranking 300k-domain study: no correlation with citations). - FAQPage / HowTo / SpeakableSpecification / multiple Article-style schemas — controlled studies show no ranking lift; one schema *worsened* a citation-prediction model in BrightEdge's analysis. - ai.txt, noai/noimageai meta tags — academic only, the site *wants* AI ingestion. - AGENTS.md repo move (gofr-dev/gofr) — separate framework PR. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The framework Dockerfile (gofr-dev/gofr/docs/Dockerfile) does COPY-then-build inside `ghcr.io/gofr-dev/website:latest`. There is no .git directory in that builder stage, so generate-doc-mtimes.mjs falls back to fs.statSync — which gives every doc the same Docker COPY timestamp, defeating the freshness signal entirely. Move it from `prebuild` to `refresh-data` (manual maintainer step): - Local dev: maintainer runs `npm run refresh-data`, real git mtimes get baked into src/data/doc-mtimes.json, JSON committed. - Docker build: prebuild only does the local-safe RSS regen; the committed mtime snapshot is served as-is. The deployed site shows real "Last updated" dates from the website repo's git history of when each doc was last touched. Far better than build-time-for-everything. Verified by `npm run build`: static export at out/ ships all 100+ routes; sitemap.xml uses the new shape (loc + lastmod only); doc pages render TechArticle + BreadcrumbList JSON-LD and the visible Last updated byline; robots.txt lists the AI/answer-bot allow-list. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Adds a `Refresh data from GitHub` step to the release_package job
that runs `yarn refresh-data` before the Docker build, with the
built-in `GITHUB_TOKEN` for auth (1000 req/hr — well above our
~150-request budget per refresh and far above the 60/hr unauth
cliff that has bitten previous local refreshes).
Why deploy-time fetch + committed snapshots, both:
- Fresh data on every release: releases.json, roadmap.json,
team-enriched.json, doc-mtimes.json all reflect the state at
the moment of deploy, not whenever a maintainer last ran
`npm run refresh-data` on their laptop.
- But never an empty site: each fetch script already has a
per-source snapshot fallback (e.g. fetch-team.mjs uses
snapshotByGithub when a profile fetch fails), and the workflow
step has `continue-on-error: true` so even a fully rate-limited
GitHub doesn't block deploy. The committed JSONs are the
last-known-good state.
Other workflow tweaks:
- `fetch-depth: 0` on checkout so generate-doc-mtimes.mjs has
the full git log to compute per-doc "Last updated" timestamps.
A shallow clone would give every doc the same boot timestamp.
- Add `setup-node` + `yarn install` to the release_package job
(previously missing — the original workflow only had Node in
the `build` job).
No PAT required: GITHUB_TOKEN suffices because all data we read
is public on github.com, and 1000 req/hr is plenty.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The website's Dockerfile builds a "source bundle" image that the framework's docs/Dockerfile then layers `npm install && npm run build` on top of. The old version copied src/, utils/, and config files but missed `public/` entirely — meaning every static asset (robots.txt, AGENTS.md, llms.txt, opengraph-image.png, security.txt, the favicon, blur orbs, …) was absent from the deployed site even though they're committed in the repo. Verified end-to-end locally by rebuilding both images and curling the resulting container: before: /robots.txt /AGENTS.md /llms.txt → 404 after: /robots.txt /AGENTS.md /llms.txt → 200 robots.txt now serves with all 21 explicit User-agent stanzas; llms.txt and AGENTS.md serve with their full bodies; the doc-page JSON-LD (TechArticle + BreadcrumbList) and the visible "Last updated" byline all render correctly through the deploy chain. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Old logic sorted contributors by raw commit count from the
/contributors API. That misses reviewers, triagers, and discussion
participants entirely — somebody who reviews 150 PRs but commits
sparingly was outranked by a one-time bulk-commit author.
New logic computes a composite score per contributor at fetch
time:
score = 1·commits
+ 5·prs_merged # gated, finished work
+ 2·reviews_authored # quality gating + mentorship
+ 0.5·comments_authored # triage + support + design
Signals come from three GitHub Search API queries per candidate:
- is:pr is:merged author:U repo:R → PRs merged by user
- is:pr reviewed-by:U repo:R → PRs they formally reviewed
- commenter:U repo:R → unique threads commented on
API budget: top 15 candidates by raw commit count × 3 calls = 45.
Throttled at 7 sec/user to stay safely under the Search API's
30/min authenticated limit (~1:54 wall time per refresh). Sized so
that anyone realistically in the running for "top 5 by composite"
is in the candidate pool — picking 15 over 5 covers the case where
a heavy reviewer's commit count puts them outside the top 5 commit-
sorted but inside the top 5 by composite.
Snapshot fallback: if a search call fails for any user, the
previous JSON value is preserved instead of dropping the signal to
zero. Existing per-source fallback for commits/contributors stays
untouched.
Result for gofr-dev/gofr today:
rank | login | score | commits | PRs | reviews | comments
-----|--------------------|-------|---------|-----|---------|---------
1 | ccoVeille | 597 | 48 | 27 | 155 | 208
2 | akshat-kumar-singhal| 136 | 44 | 10 | 14 | 28
3 | mfreeman451 | 134 | 124 | 0 | 3 | 8
4 | gizmo-rt | 115 | 58 | 6 | 8 | 23
5 | illenko | 86 | 31 | 6 | 8 | 19
ccoVeille jumps from #4 (commits only) to #1 — exactly the kind of
contributor the old logic missed.
Page treatment: heading caveat reads "Ranked by GitHub-visible
contributions … commits, merged PRs, reviews, and comments combined"
so visitors know what's measured. Each card still leads with raw
commit count (most legible single number) and shows a soft
secondary line listing PRs and reviews when non-zero. Hover title
exposes the full breakdown including comments.
Caveats explicit in code comments:
- Discussions are GraphQL-only and punted to a phase 2.
- Recency weighting is punted (Search returns lifetime totals).
- Review-quality and PR-size are not captured — every formal
review and every merged PR weight equally.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pulling out the partial-i18n surface entirely: - Footer language strip (English · Español · 简体中文) removed. - LocaleAutoRedirect (browser-language sniffing on first visit, with localStorage opt-out) removed and its mount in Layout.jsx unwired. - /es and /zh route directories deleted — they only mirrored the hero, leaving the rest of the site English. Half-translated surfaces are worse than honest English-only. - Footer imports trimmed: usePathname, clsx, React no longer needed after the language-switcher block was deleted. The rel="alternate" tags pointing at /llms.txt and /AGENTS.md stay — those are AI-discoverability hints, not language alternates. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 of 4 tasks
Two complementary publish jobs replace the single tag-only flow,
so the framework's stage deploy can track gofr-dev/website's main
branch via :stage while prod stays anchored to tagged releases.
publish_stage (new):
- Fires on push to main, on a daily cron at 04:00 UTC, and via
workflow_dispatch.
- Runs `yarn refresh-data` so :stage bakes in fresh releases /
roadmap / team / doc-mtimes on every publish.
- Tags ghcr.io/gofr-dev/website:stage.
- Cron exists so :stage picks up new GoFr releases / maintainer
activity even between merges. workflow_dispatch is the manual
button for ad-hoc refreshes.
release_package (existing behavior, body unchanged):
- Fires on tag v* push.
- Publishes ghcr.io/gofr-dev/website:<tag> + :latest with fresh
data. Prod tracks tags.
The framework-side companion (gofr-dev/gofr#3370) parameterizes
docs/Dockerfile to accept WEBSITE_TAG, points website-stage.yml at
:stage, and adds inline refresh + local source-bundle build to
website-prod.yml so prod always ships with current data on every
GoFr `v*.*.*` tag.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removed publish_stage job and the cron / push-to-main triggers.
Stage and prod in the framework repo now both check out this
website source, run yarn refresh-data, and build their source-bundle
in-runner — so neither needs a pre-published :stage on ghcr.
What this trims:
- ~120 unnecessary CI runs/month (the daily cron)
- Surprise 05:00 UTC stage rollouts
- The two-layer cron/staleness coordination headache
Workflow now only fires on:
- push tag v* → release_package publishes :latest + :vX.Y.Z
(kept as the public artifact + rollback target)
- PR to main/development → build job only (no publish)
Companion change in gofr-dev/gofr#3370 ports the inline-refresh
pattern from website-prod.yml to website-stage.yml.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…deploys
Restores the publish_stage job removed in the previous commit. The
framework's stage workflow pulls :stage rather than rebuilding the
website source from scratch on every push to development, so :stage
needs to exist as a published image keyed to website main.
Triggers:
- push to main → publish :stage with fresh data
- workflow_dispatch → manual refresh of :stage on demand
(e.g. right after a GoFr release lands)
What this is NOT:
- Not a public artifact (that's :latest, published on tag).
- Not on a schedule. Data freshness is tied to actual main merges
and the explicit workflow_dispatch button — no surprise overnight
rollouts.
Prod deploys (gofr-dev/gofr's website-prod.yml) still inline-rebuild
the source-bundle locally on every framework v*.*.* tag, so prod
freshness is independent of when :stage was last refreshed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
aryanmehrotra
added a commit
to gofr-dev/gofr
that referenced
this pull request
May 1, 2026
Moves framework-specific content out of gofr-dev/website and into
this repo, mirroring how docs/quick-start/, docs/advanced-guide/,
docs/datasources/, docs/references/, docs/events.json, and
docs/testimonials.json already work — content lives where the
framework lives, design lives in the website repo.
Marketing pages (14 .md files):
docs/why-gofr/page.md
docs/comparison/page.md + 4 sub-pages (gofr-vs-{gin,fiber,echo,chi})
docs/migrate/page.md + 5 sub-pages (from-{gin,fiber,express,flask,spring-boot})
docs/learn/page.md
docs/faq/page.md
Framework-content data files (4):
docs/team.json — maintainers list
docs/showcase/companies.json — companies using GoFr
docs/examples/examples.json — runnable examples index
docs/AGENTS.md — curated rules for AI assistants
What this means for editing:
- Update a comparison page or fix a typo in /faq → PR here, in this
repo, alongside any related framework change. No cross-repo PR.
- Add a maintainer or roll a contributor → edit team.json here.
- Refine an AGENTS.md rule → edit here. /AGENTS.md served from
this content via the website's overlay.
What stays in the website repo (gofr-dev/website):
- All layouts and JSX components (the rendering chrome).
- Build pipeline, fetcher scripts, design tokens.
- Build-time-generated JSON (releases, roadmap, team-enriched,
doc-mtimes) — output of CI fetchers, not source content.
- Site-discovery metadata: public/llms.txt, robots.txt, humans.txt,
.well-known/security.txt — about the site as a whole, not
framework specifics.
docs/Dockerfile updated with 9 new COPY directives, all pointing at
the same destinations the website previously held the files at:
COPY docs/why-gofr /app/src/app/why-gofr
COPY docs/comparison /app/src/app/comparison
COPY docs/migrate /app/src/app/migrate
COPY docs/learn /app/src/app/learn
COPY docs/faq /app/src/app/faq
COPY docs/team.json /app/src/data/team.json
COPY docs/showcase/companies.json /app/src/app/showcase/companies.json
COPY docs/examples/examples.json /app/src/app/examples/examples.json
COPY docs/AGENTS.md /app/public/AGENTS.md
Companion change in gofr-dev/website#211 removes these 18 files
from that repo so there's exactly one source of truth.
Sequencing: this PR can land first — stage/prod keep working off
the website's current copies until the website removes them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
These 18 files are framework-specific content — positioning, comparisons, migration guides, the maintainer list, the AI-assistant rule sheet — and they should evolve in lockstep with the framework. They now live in gofr-dev/gofr/docs/ and overlay this tree at deploy time, exactly how docs/quick-start, docs/advanced-guide, events.json, testimonials.json, and navigation.js already work. Companion: gofr-dev/gofr#3370 adds these files there + the 9 new COPY directives in docs/Dockerfile. Removed from this repo: src/app/why-gofr/page.md src/app/comparison/page.md + 4 sub-pages src/app/migrate/page.md + 5 sub-pages src/app/learn/page.md src/app/faq/page.md src/data/team.json src/app/showcase/companies.json src/app/examples/examples.json public/AGENTS.md What stays in this repo (per the design/infrastructure principle): - All layouts and JSX components (rendering chrome) — the layout.jsx in why-gofr/, comparison/*, migrate/*, learn/, faq/, showcase/, examples/ remain so Next.js routing keeps working when the .md or .json gets dropped in by the framework's Dockerfile. - Build pipeline (utils/*.mjs, package.json, next.config.mjs, tailwind.config.js). - Build-time-generated JSON (releases, roadmap, team-enriched, doc-mtimes) — outputs of CI fetchers. - Site-discovery metadata: public/llms.txt, robots.txt, humans.txt, .well-known/security.txt — about the site as a whole. Local dev caveat: routes that depend on the overlaid files will 404 locally until either (a) the framework's Dockerfile is exercised or (b) someone clones gofr-dev/gofr and symlinks the content tree. Same caveat already applies to /docs/* — handled identically. Sequencing: gofr-dev/gofr#3370 must merge first so the framework docs/ has the content; then this commit removes the local copies. The deploy pipeline (gofr-dev/gofr's website-stage.yml and website-prod.yml) checks out gofr-dev/website, builds source-bundle locally, and overlays framework docs/ — so the deploy chain reads content from gofr-dev/gofr regardless of whether this repo's local copies exist. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
aryanmehrotra
added a commit
to gofr-dev/gofr
that referenced
this pull request
May 1, 2026
Moves framework-specific content out of gofr-dev/website and into
this repo, mirroring how docs/quick-start/, docs/advanced-guide/,
docs/datasources/, docs/references/, docs/events.json, and
docs/testimonials.json already work — content lives where the
framework lives, design lives in the website repo.
Marketing pages (14 .md files):
docs/why-gofr/page.md
docs/comparison/page.md + 4 sub-pages (gofr-vs-{gin,fiber,echo,chi})
docs/migrate/page.md + 5 sub-pages (from-{gin,fiber,express,flask,spring-boot})
docs/learn/page.md
docs/faq/page.md
Framework-content data files (4):
docs/team.json — maintainers list
docs/showcase/companies.json — companies using GoFr
docs/examples/examples.json — runnable examples index
docs/AGENTS.md — curated rules for AI assistants
What this means for editing:
- Update a comparison page or fix a typo in /faq → PR here, in this
repo, alongside any related framework change. No cross-repo PR.
- Add a maintainer or roll a contributor → edit team.json here.
- Refine an AGENTS.md rule → edit here. /AGENTS.md served from
this content via the website's overlay.
What stays in the website repo (gofr-dev/website):
- All layouts and JSX components (the rendering chrome).
- Build pipeline, fetcher scripts, design tokens.
- Build-time-generated JSON (releases, roadmap, team-enriched,
doc-mtimes) — output of CI fetchers, not source content.
- Site-discovery metadata: public/llms.txt, robots.txt, humans.txt,
.well-known/security.txt — about the site as a whole, not
framework specifics.
docs/Dockerfile updated with 9 new COPY directives, all pointing at
the same destinations the website previously held the files at:
COPY docs/why-gofr /app/src/app/why-gofr
COPY docs/comparison /app/src/app/comparison
COPY docs/migrate /app/src/app/migrate
COPY docs/learn /app/src/app/learn
COPY docs/faq /app/src/app/faq
COPY docs/team.json /app/src/data/team.json
COPY docs/showcase/companies.json /app/src/app/showcase/companies.json
COPY docs/examples/examples.json /app/src/app/examples/examples.json
COPY docs/AGENTS.md /app/public/AGENTS.md
Companion change in gofr-dev/website#211 removes these 18 files
from that repo so there's exactly one source of truth.
Sequencing: this PR can land first — stage/prod keep working off
the website's current copies until the website removes them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Removed 56 src/app/docs/**/page.md files, three docs screenshot PNGs, and three top-level marketing pages that were accidentally checked in by an early `git add -A`. All of these are overlaid by gofr-dev/gofr's docs/Dockerfile at deploy time, so they don't belong in this repo's source. What got removed (now framework-only): src/app/docs/advanced-guide/ (20 page.md) src/app/docs/datasources/ (15 page.md, incl. nested migrations) src/app/docs/quick-start/ (7 page.md) src/app/docs/references/ (4 page.md) src/app/docs/page.md (1) public/jaeger-traces.png public/quick-start-logs.png public/quick-start-trace.png What's restored as snapshots (imported by JSX or scripts at build time, so the local build needs them — framework's overlay still wins at deploy): src/data/team.json src/app/showcase/companies.json src/app/examples/examples.json public/AGENTS.md What stays as snapshots (already-committed pattern, not changed this round): src/app/events/events.json src/lib/navigation.js utils/testimonials.json Net effect on PR diff: -12,165 lines, +170 lines, 64 files touched in this commit alone — most of the previous PR weight was the duplicated docs content. Verified: `npm run build` succeeds, all routes still emit, the framework Dockerfile's COPY directives unchanged so deploy still works (it just no longer overwrites pre-existing copies). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Five external audit reports converged on a small set of high-leverage fixes. Landing them all at once. Critical: - Soft-404 on /docs fixed at the framework side (next commit on gofr-dev/gofr#3370): nextjs.metadata frontmatter added to docs/page.md so the route renders a real <title>. - Broken hreflang alternates (/es, /zh — both routes 404) removed from src/app/page.jsx. Google flagged these in Search Console as page-level errors on every site URL. - /pkg/** redirect stubs (23 routes, no SEO content, just PkgRedirect → /docs) now ship with `robots: noindex,nofollow` via src/app/pkg/layout.jsx and are excluded from sitemap.xml. Same for /cli/** and /releases. These were 27 of the orphan URLs the audit flagged. - FAQPage JSON-LD now auto-emits on /faq. Previously FaqList only generated the schema when an explicit `items={[...]}` prop was passed; the Markdoc {% faq %}{% faq-item %} pattern doesn't pass one. Refactored FaqList to walk its React children, extract question + answer text, and emit FAQPage schema regardless of whether items was supplied. Single highest-leverage AEO fix — unlocks Google AI Overview citation eligibility for Q/A queries. - <main id="main"> landmark + skip-to-main link added to src/components/Layout.jsx. WCAG 2.4.1 (Bypass Blocks) was failing on every page. - DocStructuredData now reads doc-mtimes.json directly to populate schema.org dateModified instead of relying on the caller to pass lastUpdated. The caller (DocsLayout) wasn't passing it, so every TechArticle in the wild was missing dateModified — invisible freshness signal. High: - alt="Transistor" (from a stale tutorial template) repeated on 11 marquee logos (DBlistComponent.jsx) and 9 trusted-companies logos (CompanyTrustedList.jsx) — both now use real names ("Redis", "Kafka", "American Express", etc.) sourced from the data array. - prefers-reduced-motion: reduce honored in src/styles/prism.css — the 30s scrolling marquee freezes and lays items out statically for users who've requested reduced motion at OS level. WCAG 2.3.3. - generate-doc-mtimes.mjs now walks /why-gofr, /comparison, /migrate, /learn, /faq in addition to /docs — so every overlay- content page gets a real "Last updated" byline + dateModified instead of only the docs tree. What stays as snapshots (no change needed): - src/data/doc-mtimes.json regenerates on next refresh-data run. - Sitemap auto-rebuilds at next build. What's NOT in this commit (followups): - /docs/quick-start/introduction lead-with-Prerequisite issue — framework PR concern. - Per-route OG/Twitter card overrides — bigger change, separate commit. - Accordion <div onClick> → <button> — separate commit, isolated. - /llms-full.txt generator — separate commit. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Three more audit findings landed in one go:
a11y — Accordion now native <button>
- src/components/Accordion.jsx wrapped its content in <div onClick>
with no role/tabIndex/keyboard handler. Replaced with <button
type="button" aria-expanded={isOpen}>. Now activatable by Enter
and Space, reachable via keyboard, exposes role=button to AT.
- Inner decorative <button>+arrow image collapsed to a plain
aria-hidden=true Image (parent <button> already handles
activation; nested interactive elements were redundant + wrong).
aeo — /llms-full.txt now actually exists
- AGENTS.md advertises https://gofr.dev/llms-full.txt as the
"everything-in-one-file" variant for Anthropic Files API / OpenAI
Assistants File Search / ChatGPT custom GPT knowledge bases. The
URL was 404. utils/generate-llms-full.mjs walks every Markdoc
page, strips frontmatter, concatenates with route-prefixed H2s
per page, emits public/llms-full.txt. Wired into prebuild and
refresh-data.
- robots.txt comment annotation, sitemap.xml, and the layout's
<link rel="alternate" type="text/plain"> all now reference it.
quick-start intro page (framework PR companion change)
- gofr-dev/gofr/docs/quick-start/introduction/page.md previously
led with "# Prerequisite" — failed Princeton GEO's "first 200
words contains the answer" rule. Replaced with "# Hello, GoFr"
+ a 1-sentence definition + a 1-sentence promise of what the
page delivers, before any prerequisites. AI Overview / Perplexity
citation eligibility for "what is GoFr" / "go framework with
observability" queries.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
team - Removed Srijan Rastogi from src/data/team.json. Re-ran fetch-team.mjs to regenerate team-enriched.json — now 5 core members, 129 community contributors (Srijan moves into the community grid since he's still an active gofr-dev/gofr contributor). fetch-team.mjs - Added a framework-fallback path: when src/data/team.json is missing locally (which is the long-term direction — team.json lives in gofr-dev/gofr/docs/ and overlays at deploy), the script now falls back to ../gofr/docs/team.json if the sibling clone is available. Lets a maintainer run `yarn refresh-data` from the website repo without first hand-copying team.json over. The companion deletion of Srijan from gofr-dev/gofr/docs/team.json landed in PR #3370 (next push). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
aryanmehrotra
added a commit
to gofr-dev/gofr
that referenced
this pull request
May 1, 2026
Per maintainer team decision. Srijan Rastogi remains in the gofr-dev/gofr contributor history and will continue to appear in the community contributor grid on /team (sourced live from the GitHub contributors API at deploy time), just not in the core maintainer cards row above it. Companion change in gofr-dev/website#211 regenerates the website's team-enriched.json snapshot to reflect the new 5-maintainer roster. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… & preconnect - next.config.mjs: extend Markdoc loader to derive openGraph/twitter title+description from each page's frontmatter so /comparison, /faq, /why-gofr, /migrate/*, /learn, and /docs/** stop inheriting the home page's social card. Authors can still override via nextjs.metadata.openGraph in frontmatter. - src/app/layout.jsx: hoist hardcoded <meta og:*> JSX into the metadata export so Next's metadata-merge actually runs; drop root-level alternates.canonical='/' that was branding every subpage as a duplicate of home. - src/components/Hero.jsx: bump subtitle/tertiary text from slate-400/500 to slate-300/400 for WCAG AA contrast on slate-900; lazy-load decorative blur orbs and mark them aria-hidden. - src/components/Search.jsx: add aria-label to the search input (no visible label). - src/app/team/layout.jsx: preconnect + dns-prefetch to avatars.githubusercontent.com to cut DNS+TLS RTT on first paint of the contributor wall. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous commit emitted openGraph: { type: 'article' } unconditionally
on every Markdoc page. Next's metadata merge replaces openGraph as a whole
key (it does not deep-merge), so doc pages without nextjs.metadata frontmatter
ended up with og:title and og:description stripped instead of inheriting the
root layout's defaults.
Fix: only emit page-level openGraph / twitter when the page actually
contributes a title, description, or explicit override block. Otherwise omit
the keys so parent layout values pass through unchanged.
Verified against /docs/quick-start/configuration (no frontmatter → inherits
home og:title) and /comparison/gofr-vs-gin (frontmatter → unique og:title).
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Roadmap data currently has milestones=[] and every item carries milestone=null, so the only group rendering was the catch-all "Without a milestone" bucket. The label looked like a placeholder / debug string in production. Drop the heading text when the group has no milestone — items still render in a flat grid below the page header. When milestones come back, the section heading reappears automatically. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
P0: - Hero.jsx: fix `x:px-12` typo → `xs:px-12`; the real `xs:` 10px breakpoint defined in tailwind.config.js was never applied because of the missing `s`. Grid padding now activates on phones. - Hero.jsx: code editor wrapper text-sm → `text-xs sm:text-[13px]` so long code lines stay readable instead of forcing zoom on phones. - Reviews.jsx: `mx-10` → `mx-4 sm:mx-10` (16px margin on phones); `md:columns-3` → `sm:columns-2 md:columns-3` (2-col tablet step). P1: - MobileNavigation.jsx: drawer `max-w-xs` → `max-w-[85vw] sm:max-w-xs` so it leaves a 15vw safe-zone on tiny phones. - team/page.jsx: wrap social-icon links with `min-h/w-[36px] p-2 -m-2` so the touch target reaches WCAG 2.5.5 minimums; visual icon size unchanged at desktop. - roadmap/page.jsx: bump label/metadata `text-[10px]`/`text-[11px]` to responsive `text-[11px] sm:text-[10px]` etc — readable at 320px. P2: - Reviews.jsx: add `min-w-0`/`truncate` so long author names don't push the avatar off-screen. - Fence.jsx: code blocks `text-[13px]` → `text-xs sm:text-[13px]`. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Page weight + critical-path:
- HomePage.jsx: blur orbs drop `unoptimized` and `priority`, switch to
`loading="lazy"` + proper `width`/`height` so Next can serve WebP/AVIF
responsives. Add `pointer-events-none`, `select-none`, `aria-hidden`
+ `hidden sm:block` so the decorative 200+ KB PNGs don't load on
phones at all.
- VerticalTimeline.jsx: same blur-orb treatment.
Bugsnag (Layout.jsx):
- Replace eager `import { ErrorBoundary } from './BugsnagWrapper'` with
in-file LazyBugsnagBoundary that dynamic-imports `@bugsnag/js` +
`@bugsnag/plugin-react` via requestIdleCallback. Until ready, a tiny
componentDidCatch fallback keeps the UX intact (errors silently
no-op pre-init, acceptable given 99% of users never trigger them).
GitHub stars (Layout.jsx + new util):
- Replace render-blocking `useEffect` GitHub fetch with build-time
snapshot at `src/data/github-stars.json`. New utils/fetch-github-stars.mjs
mirrors the fetch-team.mjs pattern (snapshot fallback on API failure,
optional GITHUB_TOKEN). Wired into `npm run refresh-data`. Optional
once-per-session client refresh keeps long-lived browsers fresh,
gated by sessionStorage so it doesn't fire on every navigation.
`'use client'` audit (removed where the directive was load-bearing only
out of habit — these components have no state/effects/handlers/browser
APIs and can render server-side):
- Footer.jsx, LatestReleaseBadge.jsx, SectionCards.jsx
- src/app/{comparison,docs,faq,learn,migrate,why-gofr}/layout.jsx (each
was a one-liner wrapping a server component)
Footer hierarchy fix (addresses the "Documentation/Quick Start look the
same" complaint — they're footer column links sitting under a column
heading that wasn't visually differentiated enough):
- Column heading restyled `text-sm font-semibold text-white` →
`text-xs uppercase tracking-wider text-slate-400`. Standard footer
label treatment — the heading now reads as a small all-caps label
clearly above the sentence-case links instead of merging into them.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
The previous version gated the runtime fetch behind a sessionStorage flag — meaning after the first navigation, the header stayed pinned to whatever number was in src/data/github-stars.json (the build-time snapshot). Users with stale browser caches saw the seed value (1.9K) even after we'd rebuilt with the real count. Restore the original "real-time" behaviour: the build-time snapshot gives an instantly-correct first paint, then a background fetch on every mount silently replaces it with the truly current number. Use `stargazers_count` (the canonical field) and fall back to the legacy `watchers` alias for safety. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Fence.jsx — when a markdown fence is written without a language tag (``` instead of ```go), prism-react-renderer's Highlight crashes the entire page prerender on `language.toLowerCase()`. Fall back to 'text' so a missing tag becomes a soft degrade (plain code block, no syntax colors) instead of a hard build failure. Same crash pattern that broke v1.56.2 and was patched in v1.56.3 (per releases.json). Hero.jsx — revert the xs:px-12 mobile "fix". The original `x:px-12` was a typo that never matched any breakpoint, so the visual was designed around `px-4` (16px) being the only horizontal padding. The typo correction silently activated a real `xs:` breakpoint (defined as 10px in tailwind.config.js, i.e. always-on) which jumped the hero's horizontal padding to 48px on every screen — narrowing the content and exposing the feature cards that used to sit below the fold. Drop the class entirely; the layout returns to its original proportions. package.json — wire `node utils/fetch-github-stars.mjs` into the prebuild step so every Docker container build refreshes the baked-in star count instead of serving the seed snapshot. Combined with the earlier dynamic-stars patch in Layout.jsx, the header now (a) gets the truly current count at build time, and (b) live-refreshes on every page mount. src/data/github-stars.json — refreshed snapshot. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Setting `images: { unoptimized: true }` in next.config.mjs is the
official fix for static-export sites. Without it, Next's <Image>
component emits `/_next/image?url=...` srcs that 404 at runtime
under output: 'export' (the optimisation API is server-only) — the
browser falls back to its broken-image placeholder.
This regressed when the perf batch dropped per-component
`unoptimized` props in HomePage.jsx and VerticalTimeline.jsx
(visible as the broken-image artefact on /events between event
cards in user-reported screenshots). The config-level switch covers
every <Image> usage at once so we don't have to remember the prop
on each new image.
Also keep belt-and-suspenders `unoptimized` on the two decorative
blur-orb <Image>s (HomePage + VerticalTimeline) so the intent is
explicit even if someone flips the global later.
Verified every previously-broken URL on /events now returns 200:
- /_next/static/media/blur-cyan.d28a5585.png
- /events/hackathon.jpg
- /events/OpenSourceIndia.jpeg
- /events/gopherconAfrica.jpeg
- /events/WorkShop.jpeg
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Visual / interaction:
- Hero: revert dead-code `xs:px-12` → no class (preserves prod proportions);
bump code-editor body to text-sm on desktop to match prod scale;
remove the LatestReleaseBadge + AI/llms tertiary, restore prod's
"Want to evaluate and adopt GoFr at your org? block our calendar."
CTA pointing at the existing Calendly URL; remove `unoptimized`
bypass per the static-export image fix; gentle gopher drift via
motion-safe:animate-gentle-drift; line-by-line stagger reveal on
the code lines via motion-safe:animate-line-in.
- HomePage: density-matched section padding (Vercel/Stripe pattern) —
thin marquee strip py-8, logo wall py-12, ecosystem/testimonials
py-20, feature-card grid py-20. Replaces uniform py-24 which was
producing visible dead air on thin sections.
- Footer: "Documentation" → "Production Guides" (links the new
/docs/guides/* tree); column heading becomes uppercase tracking-
wider so the heading-to-link hierarchy is unmistakable.
- New: FadeInOnScroll, StaggerChildren, CountUp helpers (no new
deps; pure IntersectionObserver). FadeInOnScroll wraps every
trailing section so they fade up/down on scroll. StaggerChildren
ripples the 6 feature cards in left→right. CountUp animates 0 →
21,500 on the trusted-by line when it scrolls into view.
- Cards: 1 px hover lift on QuickLinks + Ecosystem cards.
- Color seams removed: bg-gray-900 stripped from DBlistComponent +
CompanyTrustedList, bg-[#101827] stripped from Reviews. Page now
reads as one continuous bg-slate-900 from hero to footer.
- prefers-reduced-motion now PAUSES the marquee animation in place
rather than disabling it (the `position: static` fallback was
collapsing all items to the same coordinate and hiding the row).
Static-export image fix:
- next.config.mjs `images: { unoptimized: true }` so /_next/image
is no longer emitted under output: 'export'. Without this, every
<Image> rendered a /_next/image?url=... src that 404'd in
production and showed as a browser broken-image icon (visible
on /events/ and on the homepage's blur orb).
SEO / AEO:
- Markdoc loader (next.config.mjs) now derives a per-page
`alternates.canonical` from the source-tree path, in addition to
the openGraph/twitter title+description it already auto-fills.
Result: every Markdoc page emits a unique <link rel="canonical">.
- Layout / page metadata: home description padded from 70 chars
→ 150 chars; cli/gofr/page.jsx and 23 /pkg/**/page.jsx redirect
stubs each now export a sensible local metadata.title (parent
noindex preserved).
- DocsHeader: removed the manual <title> + <meta description> tags
it was injecting from inside the React tree. They duplicated the
canonical pair Next's metadata API already emits — Google was
being shown two titles and free to pick the wrong one.
Single root cause for ~25 doc pages losing their SEO title.
- robots.txt: added explicit allow stanzas for CCBot and Bytespider
(Common Crawl + Bytedance) alongside the existing GPTBot /
ClaudeBot / PerplexityBot / Google-Extended / Applebot-Extended /
Meta-ExternalAgent set.
- llms.txt: added the 8 newer migration pages (Echo, chi, NestJS,
FastAPI, Django REST, ASP.NET Core, Laravel, Rails).
- utils/generate-llms-full.mjs walker: added a "Production guides"
section so the dockerizing / helm-chart / k8s-deploy guides flow
into the dump on the next refresh.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR is a large website overhaul for gofr.dev focused on SEO/AEO, AI-discoverability, fresher build-time data, and broader marketing/documentation surface area. It adds new public entry points and metadata infrastructure while also reshaping key user-facing pages like home, changelog, examples, showcase, roadmap, and team.
Changes:
- Added SEO/AEO infrastructure: route metadata, structured data, AI-facing resources (
AGENTS.md,llms.txt,llms-full.txt), dynamic sitemap, robots/security/humans files, and docs freshness data. - Added or reworked major site surfaces: homepage, examples, showcase, roadmap, changelog, events, team, FAQ/docs helpers, and multiple new shared UI components.
- Replaced several runtime fetches/manual copy paths with build-time GitHub-driven snapshots and updated CI/build scripts to refresh/publish generated assets.
Reviewed changes
Copilot reviewed 109 out of 118 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| utils/generate-llms-full.mjs | Generates concatenated AI-facing docs dump. |
| utils/generate-doc-mtimes.mjs | Builds route-to-last-modified JSON from git history. |
| utils/generate-changelog-rss.mjs | Generates RSS feed from changelog snapshot. |
| utils/fetch-roadmap.mjs | Fetches milestones/issues into roadmap snapshot. |
| utils/fetch-releases.mjs | Fetches GitHub releases into changelog data. |
| utils/fetch-github-stars.mjs | Fetches GitHub star count snapshot. |
| tailwind.config.js | Adds homepage animation keyframes/utilities. |
| src/styles/prism.css | Refines inline code styling and reduced-motion handling. |
| src/markdoc/tags.js | Registers new Markdoc tags/components. |
| src/markdoc/search.mjs | Improves search title parsing and scoring. |
| src/data/team.json | Adds maintainer/team source data. |
| src/data/github-stars.json | Commits star-count snapshot. |
| src/data/doc-mtimes.json | Commits generated last-modified snapshot. |
| src/components/goforgofr/GFGTracks.jsx | Removes old company reference. |
| src/components/VerticalTimeline.jsx | Fixes decorative image behavior/loading. |
| src/components/Tabs.jsx | Adds client-side tab UI component. |
| src/components/StaggerChildren.jsx | Adds staggered reveal container. |
| src/components/SectionCards.jsx | Adds navigation card grid component. |
| src/components/Reviews.jsx | Tweaks testimonial layout responsiveness. |
| src/components/QuickLinks.jsx | Adds hover motion to quick links. |
| src/components/Prose.jsx | Updates prose typography/tables/code styling. |
| src/components/PkgRedirect.jsx | Adds redirect UI for package vanity routes. |
| src/components/Navigation.jsx | Converts docs nav to collapsible client nav. |
| src/components/MobileNavigation.jsx | Expands mobile nav with top-level site links. |
| src/components/MarketingPage.jsx | Adds wrapper for SEO landing pages. |
| src/components/Layout.jsx | Reworks global layout/header/error boundary/stars handling. |
| src/components/LatestReleaseBadge.jsx | Adds release badge from changelog data. |
| src/components/LastUpdatedByline.jsx | Adds visible last-updated byline from snapshot data. |
| src/components/HowTo.jsx | Adds HowTo renderer + JSON-LD. |
| src/components/HomePage.jsx | Reorders homepage sections and adds motion wrappers. |
| src/components/Hero.jsx | Refines hero copy, CTAs, visuals, and code animation. |
| src/components/Footer.jsx | Rebuilds footer information architecture. |
| src/components/Fence.jsx | Redesigns fenced code blocks and copy UI. |
| src/components/Faq.jsx | Adds FAQ accordion + FAQPage JSON-LD support. |
| src/components/FadeInOnScroll.jsx | Adds section fade-on-scroll wrapper. |
| src/components/EcosystemRecognition.jsx | Adds ecosystem recognition credibility strip. |
| src/components/DocsLayout.jsx | Adds structured data and last-updated support to docs layout. |
| src/components/DocsHeader.jsx | Removes duplicate head metadata from visible docs header. |
| src/components/DocStructuredData.jsx | Adds doc JSON-LD output. |
| src/components/DBlistComponent.jsx | Improves datasource marquee accessibility/content. |
| src/components/CountUp.jsx | Adds animated counter component. |
| src/components/CompanyTrustedList.jsx | Reworks company/social proof block. |
| src/components/Answer.jsx | Adds answer callout component. |
| src/components/Accordion.jsx | Improves accordion accessibility semantics. |
| src/app/why-gofr/layout.jsx | Applies marketing-page wrapper. |
| src/app/team/layout.jsx | Adds metadata and avatar CDN preconnect intent. |
| src/app/sitemap.xml | Removes old static sitemap. |
| src/app/sitemap.js | Adds dynamic sitemap generation. |
| src/app/showcase/page.jsx | Adds showcase page with companies/testimonials. |
| src/app/showcase/layout.jsx | Adds showcase route metadata. |
| src/app/showcase/companies.json | Adds showcase company list. |
| src/app/roadmap/page.jsx | Adds roadmap page driven by snapshot data. |
| src/app/roadmap/layout.jsx | Adds roadmap route metadata. |
| src/app/releases/layout.jsx | Replaces old releases layout with client redirect. |
| src/app/pkg/layout.jsx | Adds noindex layout for package vanity routes. |
| src/app/pkg/gofr/datasource/surrealdb/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/solr/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/scylladb/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/pubsub/sqs/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/pubsub/nats/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/pubsub/eventhub/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/oracle/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/opentsdb/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/mongo/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/kv-store/nats/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/kv-store/badger/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/file/sftp/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/file/s3/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/file/gcs/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/file/ftp/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/file/azure/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/elasticsearch/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/dgraph/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/dbresolver/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/couchbase/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/clickhouse/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/cassandra/page.jsx | Converts vanity route to redirect page. |
| src/app/pkg/gofr/datasource/arangodb/page.jsx | Converts vanity route to redirect page. |
| src/app/page.jsx | Expands homepage metadata and adds JSON-LD. |
| src/app/not-found.jsx | Rebuilds 404 page with search/helpful links. |
| src/app/migrate/layout.jsx | Applies marketing-page wrapper. |
| src/app/learn/layout.jsx | Applies marketing-page wrapper. |
| src/app/layout.jsx | Moves global metadata into Next metadata API and adds AI discovery links. |
| src/app/faq/layout.jsx | Applies marketing-page wrapper. |
| src/app/examples/page.jsx | Adds examples/recipes landing page. |
| src/app/examples/layout.jsx | Adds examples route metadata. |
| src/app/examples/examples.json | Adds example catalog data. |
| src/app/events/layout.jsx | Adds events route metadata. |
| src/app/events/events.json | Refreshes event content/image sources. |
| src/app/docs/layout.jsx | Removes unnecessary client directive. |
| src/app/comparison/layout.jsx | Applies marketing-page wrapper. |
| src/app/cli/gofr/page.jsx | Replaces placeholder CLI page with actual landing content. |
| src/app/changelog/layout.jsx | Adds changelog route metadata. |
| public/robots.txt | Adds crawler/AI bot policy and sitemap reference. |
| public/quick-start-trace.png | Adds public asset for docs/site content. |
| public/quick-start-logs.png | Adds public asset for docs/site content. |
| public/llms.txt | Adds curated LLM link index. |
| public/llms-full.txt | Commits generated full-content LLM dump. |
| public/jaeger-traces.png | Adds public asset for docs/site content. |
| public/humans.txt | Adds humans.txt metadata file. |
| public/AGENTS.md | Adds AI assistant guidance document. |
| public/.well-known/security.txt | Adds RFC 9116 security contact file. |
| package.json | Adds prebuild and refresh-data scripts. |
| next.config.mjs | Enables export-safe images and richer Markdoc metadata generation. |
| Dockerfile | Copies public assets into image build context. |
| .github/workflows/package.yml | Expands CI/publishing workflow for stage/latest images and data refresh. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+78
to
+90
| - [Migrating from Gin](https://gofr.dev/migrate/from-gin) | ||
| - [Migrating from Fiber](https://gofr.dev/migrate/from-fiber) | ||
| - [Migrating from Echo](https://gofr.dev/migrate/from-echo) | ||
| - [Migrating from chi](https://gofr.dev/migrate/from-chi) | ||
| - [Migrating from Express (Node.js)](https://gofr.dev/migrate/from-express) | ||
| - [Migrating from NestJS (TypeScript)](https://gofr.dev/migrate/from-nestjs) | ||
| - [Migrating from Flask (Python)](https://gofr.dev/migrate/from-flask) | ||
| - [Migrating from FastAPI (Python)](https://gofr.dev/migrate/from-fastapi) | ||
| - [Migrating from Django REST (Python)](https://gofr.dev/migrate/from-django-rest) | ||
| - [Migrating from Spring Boot (Java)](https://gofr.dev/migrate/from-spring-boot) | ||
| - [Migrating from ASP.NET Core (C#)](https://gofr.dev/migrate/from-aspnet-core) | ||
| - [Migrating from Laravel (PHP)](https://gofr.dev/migrate/from-laravel) | ||
| - [Migrating from Rails (Ruby)](https://gofr.dev/migrate/from-rails) |
| - From Chi: see <https://gofr.dev/comparison/gofr-vs-chi> | ||
| - From Express (Node.js): <https://gofr.dev/migrate/from-express> | ||
| - From Flask (Python): <https://gofr.dev/migrate/from-flask> | ||
| - From Spring Boot (Java): <https://gofr.dev/migrate/from-spring-boot> |
Comment on lines
+27
to
+37
| const SECTIONS = [ | ||
| { dir: 'src/app/docs/quick-start', label: 'Quick Start' }, | ||
| { dir: 'src/app/docs/advanced-guide', label: 'Advanced Guide' }, | ||
| { dir: 'src/app/docs/datasources', label: 'Datasources' }, | ||
| { dir: 'src/app/docs/references', label: 'References' }, | ||
| { dir: 'src/app/why-gofr', label: 'Why GoFr' }, | ||
| { dir: 'src/app/comparison', label: 'Comparison' }, | ||
| { dir: 'src/app/migrate', label: 'Migration guides' }, | ||
| { dir: 'src/app/learn', label: 'Learn' }, | ||
| { dir: 'src/app/faq', label: 'FAQ' }, | ||
| ] |
Comment on lines
+133
to
+144
| // Live refresh on every page load. The build-time snapshot in | ||
| // src/data/github-stars.json gives an instantly-correct first paint; | ||
| // this fetch then replaces it with the truly current number so the | ||
| // header stays real-time. Failures are silent — we keep the | ||
| // pre-paint number. | ||
| fetch('https://api.github.com/repos/gofr-dev/gofr') | ||
| .then((r) => (r.ok ? r.json() : null)) | ||
| .then((data) => { | ||
| const live = data?.stargazers_count ?? data?.watchers | ||
| if (typeof live === 'number') setGithubStars(live) | ||
| }) | ||
| .catch(() => {}) |
Comment on lines
+31
to
+34
| <CountUp | ||
| value={21500} | ||
| durationMs={1500} | ||
| format={(n) => `${n.toLocaleString()}+`} |
Comment on lines
+9
to
+17
| useEffect(() => { | ||
| router.replace('/changelog') | ||
| }, [router]) | ||
|
|
||
| return ( | ||
| <div className="flex min-h-[70vh] items-center justify-center"> | ||
| <p className="text-slate-500"> | ||
| Redirecting to changelog... | ||
| </p> |
Umang01-hash
approved these changes
May 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
A substantial revamp of gofr.dev focused on three things:
/why-gofr,/comparison/*,/migrate/*,/learn,/faq), a richer team page, a roadmap, and home-page reordering so substance leads./AGENTS.md,/llms.txt, FAQ/HowTo JSON-LD, dynamic sitemap.138 files changed, ~20k insertions / ~500 deletions across the two commits on this branch.
What landed
Content
/why-gofr— narrative pitch grounded in the framework's own positioning./comparison+/comparison/gofr-vs-{gin,fiber,echo,chi}— feature matrix and per-framework deep dives. Each acknowledges the competing framework's strengths so the tone stays honest, not adversarial./migrate+/migrate/from-{gin,fiber,express,flask,spring-boot}— concrete code translations./learn— three tracks (switchers / Go devs new to GoFr / production builders)./faq— long-tail Q&A grouped by topic, audited for accuracy (CockroachDB / ClickHouse mis-categorisation fixed, Go version mismatch removed, unverifiable production-readiness claims pulled)./team— auto-generated; 6 maintainers + 128 community contributors fed live from GitHub./roadmap— milestones pulled from GitHub at build time./AGENTS.md./comparison; the/benchmarkspage (kept for a future revisit when there are real numbers to publish).SEO / AEO infrastructure
nextjs.metadata.title/description) on every doc + SEO page so Google + AI Overviews see unique titles.{% answer %}— direct-answer block at the top of a doc, the kind LLMs quote.{% faq %}+{% faq-item %}— collapsible Q/A; emitsFAQPageJSON-LD.{% howto %}— numbered steps; emitsHowToJSON-LD./sitemap.xmlviafast-globwalk ofsrc/app/**/page.{md,jsx}; replaces the static file.robots.txt+.well-known/security.txt+humans.txtadded.For AI coding assistants and search engines
/AGENTS.md— curated context file. 10 core rules, a minimal app, a tight Migrations section (rules + pointer rather than inlined examples to save tokens), and a categorised where to look link index. Linked inline from the hero./llms.txt— Markdown-shaped curated link index per the llmstxt.org spec. Sectioned so AI engines can partial-fetch./llms.txt. Top-of-page + bottom-of-page placement matches audience: AGENTS.md is for the developer wiring up an assistant (hero), llms.txt is for the AI crawler (footer).Build-time data fetchers
utils/fetch-releases.mjs→src/app/changelog/releases.jsonutils/fetch-roadmap.mjs→src/data/roadmap.jsonutils/fetch-team.mjs→src/data/team-enriched.jsonutils/generate-changelog-rss.mjs→public/changelog.xml(RSS)Each fetcher has an offline-tolerant snapshot fallback so a rate-limited or offline build keeps the previously-fetched JSON rather than silently emptying it.
Build hooks adjusted: the GitHub fetchers no longer run on every build (they hit GitHub rate limits and slowed local dev). They now run only via
npm run refresh-data. Only the local-only RSS generator runs onprebuild. JSON snapshots are committed; refresh on demand or on release.i18n
/es/*) and Simplified Chinese (/zh/*) variants of the hero, withLocaleAutoRedirectpicking the user's preferred language on first visit (and storing a manual override so the user's later choice sticks).hreflangannotations on the root layout.New components
MarketingPage— chrome wrapper for SEO pages (no left sidebar, right-rail TOC kept).LatestReleaseBadge— small inline version chip in the hero fed fromreleases.json.LocaleAutoRedirect— browser-language sniffing on/.EcosystemRecognition— TW Radar / CNCF / JetBrains row with per-source metadata.Faq+FaqSearchProvider— client-side search across FAQ items.Answer/HowTo— Markdoc tag renderers.Changelog / RSS
/changelog#v1.56.0auto-expands)./changelog.xmlregenerated fromreleases.json.CSS
prism.css: removed the globalcode { background-color }rule that was painting per-line pill backgrounds on every<code>inside<pre>. Scoped to:not(pre) > code.Test plan
next devruns cleanly; home page returns 200./why-gofr,/comparison/*,/migrate/*,/learn,/faq,/team,/roadmap,/showcase,/examples,/changelog,/community,/events./AGENTS.mdand/llms.txtserve as static plaintext./sitemap.xmldynamically lists everypage.{md,jsx}route.v1.56.4fromreleases.json.{% faq %}and a doc with{% howto %}.Commits
feat: website overhaul — content, SEO/AEO, AI-discoverability, i18n— main body of workteam: add Srijan Rastogi and Vipul Rawat as maintainers— maintainer additions🤖 Generated with Claude Code