Skip to content

chore: redesign in Astro - #2169

Merged
bjohansebas merged 70 commits into
gh-pagesfrom
redesign
May 18, 2026
Merged

chore: redesign in Astro#2169
bjohansebas merged 70 commits into
gh-pagesfrom
redesign

Conversation

@bjohansebas

@bjohansebasbjohansebas commented Jan 29, 2026

Copy link
Copy Markdown
Member

Preview Url :- https://deploy-preview-2169--expressjscom-preview.netlify.app/

Important

The conflicts will be resolved when we’re ready to release it to the public, so don’t worry about that—one of the captains will handle it when the time comes.

Overview

The design aims to closely follow the original Figma as much as possible. However, due to time constraints, it was not feasible to keep it fully up to date, as Orama supported the redesign effort until April 3.

Throughout the development process, feedback was continuously gathered via Slack, and adjustments were made iteratively as the site evolved.

As part of this transition, and to provide a clear before-and-after reference for the API content, the gh-pages branch will be left untouched, while a new main branch has been introduced, which will become the default branch of the repository.

The following sections outline the key decisions that were made and explain why certain aspects of the site are implemented the way they are.

For more in-depth details on how the site works, everything is documented in the repository under the docs folder.


API Routes

At the beginning, each method and property had its own URL. Over time, we decided to group them by object (req, res, app, router) to reduce both build times and page size.

Previously, the site could reach up to 600MB due to all generated i18n pages. With this change, the build process is now significantly faster and more efficient.


Search

The original Figma proposal placed the search as a right-side panel. This was changed to a modal-based search, mainly because the original design didn’t account for having a Table of Contents (ToC) per page.

Important note:
This is the only part of the site that uses React. It was implemented following Orama’s recommendation to ensure a fast and high-quality search experience.


Menu

Compared to the Figma design, the language switcher and dark/light theme toggle were moved next to the search.

This follows a pattern similar to the Node.js website.


Versioning

The Figma design did not include page versioning. During development, we decided to introduce versioning for documentation pages.

How versioning works is documented in the repository under the docs folder.


i18n

The versioning system remains intact.

Current issue:

  • The Crowdin integration is not working properly (already in contact with their support).

For now:

  • Non-English pages are fallbacks from English.

Once fixed:

  • Proper translations will be available.

Footer

The original footer design did not follow the foundation’s recommendations.

It was updated to include the proper copyright text, which was later also added to the current expressjs.com site.


E2E testing

Setup playwright testing platform with GitHub actions. Total 48 tests are added for hero, features, theme, i18n and footer components.

Test Artifact download URL: https://github.com/expressjs/expressjs.com/actions/runs/24755732707/artifacts/6568925216


Updated Documentation

During this process, several parts of the documentation were improved:

More documentation will continue to be improved over time throughout the year with the team.


API Overview

The API now includes an overview section, improving organization and aligning with the new versioning system.


llms.txt

Support was added to generate llms.txt files from the documentation.

This allows language models to better access and understand the docs:
https://deploy-preview-2169--expressjscom-preview.netlify.app/llms.txt


OG Images

All pages now have dynamically generated Open Graph images.

Note:

  • The design does not match Figma because the feature was implemented before noticing that the Figma had been updated.

Homepage Announcement Banner

The homepage banner is now automated:

  • Displays the latest blog post for 30 days
  • Prevents forgetting to update/remove it
  • Can be overridden with custom content if needed

This behavior is documented in the docs folder.


CI: Broken Link Detection

  • A CI system now checks for broken links
  • Not perfect, but helps reduce link issues significantly

Accessibility

  • The site has been improved to be as accessible as possible
  • Any accessibility issues should be reported for further fixes

Light Mode

  • The original Figma design did not include a light mode preview
  • Light mode is now fully implemented

Issues Resolved

The following issues were closed as part of this migration (and likely more):


Final Notes

  • The blog post announcing the redesign and the logo will be created next week.
  • The logo has not been officially selected yet, but it is expected that a decision will be made this week.

Personal Note of Sebastian

Important

I’d really like to be the one to press the merge button.

The main reason I joined Express was to improve the documentation experience, and this represents the biggest step in that direction. After all the time and effort I’ve invested into this, it would mean a lot to me.

If anything needs to be fixed quickly before launch, I’m happy to jump on it and address it right away.

Summary of commits

Summary of commits

Infrastructure / Setup

Set up the Astro project from scratch, configured the Netlify deployment, and later moved the Astro project from a subdirectory to the repository root.

Details
PRDescriptionAuthorDate
#2167Initial technical setup of the Astro projectg-francesca2026-01-29
#2170Fix Netlify config to point to the Astro directoryjonchurch2026-01-29
#2253Move Astro project to the repository rootbjohansebas2026-04-02

CI/CD

Added GitHub Actions workflows for building, linting, and checking links on PRs. Set up Husky for pre-commit hooks, Dependabot for dependency updates, and fixed the Crowdin configuration for translations.

Details
PRDescriptionAuthorDate
#2168Add workflow for Astro site build and lintingbjohansebas2026-01-29
#2192Add PR link checking workflow, fix links and add fallback to english pagesbjohansebas2026-03-15
#2195Husky pre-commit hooks setupShubhamOulkar2026-03-29
#2254Add Dependabot and improve READMEbjohansebas2026-04-02
#2256Fix Crowdin config for translationsbjohansebas2026-04-03
#2288Setup playwright testing platformShubhamOulkar2026-04-22

Design / UI Components

Built the full site layout: responsive header and sidebar navigation (mobile, tablet, desktop), footer, homepage hero with optimized WebM/WebP media, features/banner sections, reusable Alert component, blog post page, breadcrumb, and documentation page layout adjustments.

Details
PRDescriptionAuthorDate
#2180Mobile header and sidebar navigationg-francesca2026-02-18
#2185Tablet/desktop header and sidebar navigationg-francesca2026-02-24
#2196Footer redesigng-francesca2026-02-25
#2203Homepage Hero componentg-francesca2026-03-04
#2204Homepage Features and Banner componentsg-francesca2026-03-04
#2205Reusable Alert componentg-francesca2026-03-05
#2208Adjust layout content width for responsive sidebarGroophyLifefor2026-03-22
#2228Blog post page redesigng-francesca2026-03-30
#2221Optimize hero media using WebM/WebP and reduce asset sizeShubhamOulkar2026-04-02
#2251Documentation page fixes and improvementsg-francesca2026-04-02
#2252Enhance breadcrumb componentShubhamOulkar2026-04-03

Features

Implemented i18n language selection, blog listing page, and search/chat powered by Orama. Added SEO essentials (sitemap, robots.txt, RSS feed, Open Graph/Twitter Cards, automatic OG image generation). Built documentation features like Table of Contents, prev/next navigation, and rehype plugins for heading links. Added support for global pages, content collections, redirects for legacy links, multi-language translation editing, scripts for pulling external docs, and LLM-friendly API endpoints. Bumped to Astro v6.

Details
PRDescriptionAuthorDate
#2197i18n language selectiong-francesca2026-03-02
#2207Blog listing pageg-francesca2026-03-13
#2213Search/chat widget powered by Oramag-francesca2026-03-24
#2217Sitemap integration and robots.txtbjohansebas2026-03-22
#2218RSS feed functionalitybjohansebas2026-03-22
#2222Redirects for blog posts and legacy API linksbjohansebas2026-03-29
#2224Open Graph and Twitter Card metadatabjohansebas2026-03-30
#2230Table of Contents for documentation layoutbjohansebas2026-03-30
#2231Remove i18n folder for blogbjohansebas2026-03-31
#2232Support page and content collections updatebjohansebas2026-03-31
#2233Support for global pagesbjohansebas2026-03-31
#2234Move resources to the page collectionbjohansebas2026-03-31
#2236Bump to Astro v6bjohansebas2026-03-31
#2237Translation option for editing pages in multiple languagesbjohansebas2026-03-31
#2239Prev/next navigation for documentation pagesbjohansebas2026-03-31
#2240Scripts for pulling external documentsbjohansebas2026-03-31
#2241RSS feed link and translations for multiple languagesbjohansebas2026-03-31
#2242Rehype plugins for automatic heading linksbjohansebas2026-03-31
#2243Overview heading in posts and improved ToCbjohansebas2026-03-31
#2259Automatic OG image generationbjohansebas2026-04-04
#2260LLMs API and documentation endpointsbjohansebas2026-04-04

Documentation

Wrote overviews for the Application and Express objects and improved API overviews. Migrated remaining Jekyll includes to Astro. Unified headings and API pages for consistency. Adopted the new Alert component across docs. Added security.txt, clustering/middleware images, and project structure documentation. Improved the v5 migration guide (including documenting removed options) and updated routing docs for separate versions.

Details
PRDescriptionAuthorDate
#2216Application and Express object overviewbjohansebas2026-03-22
#2223Better API overviewsbjohansebas2026-03-30
#2225Use the new Alert component in docsbjohansebas2026-03-30
#2229Unify headings across documentationbjohansebas2026-03-30
#2235Resolve the last Jekyll includesbjohansebas2026-03-31
#2238Update more docs for the new websitebjohansebas2026-03-31
#2244Add security.txtbjohansebas2026-03-31
#2245Clustering and middleware images for docsbjohansebas2026-03-31
#2258Unify API pagesbjohansebas2026-04-03
#2261Document project structure and morebjohansebas2026-04-04
#2262Improve migration guide to v5bjohansebas2026-04-04
#2263Update routing documentation for separate versionsbjohansebas2026-04-04
#2211Document removed options for res.sendFile() and express.static() in Express 5 migration guide22BRS13172026-04-04

@netlify

netlifyBot commented Jan 29, 2026

Copy link
Copy Markdown

Deploy Preview for expressjscom-preview ready!

NameLink
🔨 Latest commit6898491
🔍 Latest deploy loghttps://app.netlify.com/projects/expressjscom-preview/deploys/6a0b6714babec300074fa7e3
😎 Deploy Previewhttps://deploy-preview-2169--expressjscom-preview.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.
Lighthouse
Lighthouse
1 paths audited
Performance: 98 (🟢 up 2 from production)
Accessibility: 100 (🟢 up 13 from production)
Best Practices: 100 (no change from production)
SEO: 100 (🟢 up 6 from production)
PWA: 80 (🟢 up 50 from production)
View the detailed breakdown and full score reports
🤖 Make changesRun an agent on this branch

To edit notification comments on pull requests, go to your Netlify project configuration.

Comment threadsrc/styles/tokens/_typography.css
Comment threadsrc/styles/tokens/_breakpoints.css
g-francescaand others added 25 commits February 18, 2026 14:36
Co-authored-by: shubham oulkar <91728992+ShubhamOulkar@users.noreply.github.com>
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
Co-authored-by: Shubham Oulkar <oulkarshubhu@gmail.com>
Co-authored-by: shubham oulkar <91728992+ShubhamOulkar@users.noreply.github.com>
Co-authored-by: shubham oulkar <91728992+ShubhamOulkar@users.noreply.github.com>
Co-authored-by: shubham oulkar <91728992+ShubhamOulkar@users.noreply.github.com>
Co-authored-by: Shubham Oulkar <oulkarshubhu@gmail.com>
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
Co-authored-by: Shubham Oulkar <oulkarshubhu@gmail.com>
Co-authored-by: Shubham Oulkar <oulkarshubhu@gmail.com>
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
Co-authored-by: Shubham Oulkar <oulkarshubhu@gmail.com>
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>
Signed-off-by: Sebastian Beltran <bjohansebas@gmail.com>
@bjohansebas

Copy link
Copy Markdown
MemberAuthor

FYI orama logo is 404

the same thing happens in Node.js and Fastify as well. I’m already asking the Orama team where I can get those images to fix it.

expressjs express master/examples
LIST_END
) | while read org repo branch; do
# TODO: change the DEST when astro project is in the root of the repo instead of in a subdirectory.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Does this need to be changed?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

This has already been fixed, I just forgot to remove the comment.

@jonchurch

Copy link
Copy Markdown
Member

Im working through reviewing, will likely PR some changes to the redesign branch directly (mostly github actions related stuff is what Im finding some fixes for, many are things that already existed that Im just noticing now) but tryna do the review on the full context here in this PR.

But things are looking really good!

Some TODOS I have written down right now, updating the references to the redesign branch in GHA to be main. Those are last step things though of course as it would break the actions for the redesign branch before it lands.

Id prefer to keep the git history of the repo all parented to the same root. Meaning, I think we should land to gh-pages and then just rename the branch to main to keep all the history, vs starting from scratch with a new branch entirely that has a new root. Thoughts?

@bjohansebas

Copy link
Copy Markdown
MemberAuthor

Id prefer to keep the git history of the repo all parented to the same root. Meaning, I think we should land to gh-pages and then just rename the branch to main to keep all the history, vs starting from scratch with a new branch entirely that has a new root. Thoughts?

Sounds good to me. I just wanted to keep a separate branch with the old site just in case (also as a source of truth for the documentation, since there were some changes, I already mentioned them in the PR description). But that can literally be created separately, and we can merge this into gh-pages, and then rename it to main if we want.

@socket-security

This comment was marked as off-topic.

@socket-security

This comment was marked as off-topic.

Comment threadscripts/orama-documents.mjs Dismissed
Comment threadsrc/components/patterns/Sidebar/SidebarVersionManager.ts Dismissed
Comment threadsrc/components/patterns/Sidebar/SidebarVersionManager.ts Dismissed
Comment on lines +41 to +43
# node-version-file: ".nvmrc" use when .nvmrc is on root of the repo
node-version: '24.13'
# cache: "npm" use when package-lock.json is on root of the repo

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Since #2253package-lock.json and .nvmrc are in the repository root.

Suggested change
# node-version-file: ".nvmrc" use when .nvmrc is on root of the repo
node-version: '24.13'
# cache: "npm" use when package-lock.json is on root of the repo
node-version-file: '.nvmrc'
cache: 'npm'

Comment on lines +45 to +47
PUBLIC_ORAMA_PROJECT_ID: ${{ github.event_name == 'push' && secrets.PUBLIC_ORAMA_PRODUCTION_PROJECT_ID || secrets.PUBLIC_ORAMA_PROJECT_ID }}
PRIVATE_ORAMA_API_KEY: ${{ github.event_name == 'push' && secrets.PRIVATE_ORAMA_PRODUCTION_API_KEY || secrets.PRIVATE_ORAMA_API_KEY }}
PUBLIC_ORAMA_DATASOURCE_ID: ${{ github.event_name == 'push' && secrets.PUBLIC_ORAMA_PRODUCTION_DATASOURCE_ID || secrets.PUBLIC_ORAMA_DATASOURCE_ID }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Do these "non-production" secrets exist? CI on pull requests fails (e.g. here) with Endpoint and API Key are required to create a Profile, because the API key is missing (PRIVATE_ORAMA_API_KEY).

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

They do exist, but they don't work on forks since they are secrets. So what we would need to do is either prevent this workflow from running on forks, or use pull_request_target, although I’d prefer to avoid that.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

pull_request_target sounds like a bad idea.

According to actions/runner#1138, if: github.repository_owner == 'expressjs' && github.actor != 'dependabot[bot]' (or if: github.repository == 'expressjs/expressjs.com' && github.actor != 'dependabot[bot]') should skip the job in runs that do not have access to secrets (Dependabot runs from the same repo, but does not have access to secrets)

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

Yep, do you want to open a PR? As some of you already know, I have to step away from the project, so I won’t be around here for about a month.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Of course it wasn't so simple and the if from comment above did not work - #2297.

jonchurchand others added 2 commits April 25, 2026 10:08
Co-authored-by: Crowdin Bot <support+bot@crowdin.com>
Co-authored-by: Sebastian Beltran <bjohansebas@gmail.com>

@wesleytoddwesleytodd left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

LGTM! Thanks for all the great wrok on this everyone. Really looking awesome.

@bjohansebas
bjohansebas merged commit b92f289 into gh-pagesMay 18, 2026
18 of 21 checks passed
@bjohansebas
bjohansebas deleted the redesign branch July 5, 2026 04:32
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

11 participants

@bjohansebas@AugustinMauroy@jonchurch@wesleytodd@krzysdz@github-advanced-security@ShubhamOulkar@logeshmassking-max@g-francesca@GroophyLifefor@chakri11-git