Skip to content

docs: replace the homepage with the reactnativepaper.com landing page - #5138

Open
rjmreis wants to merge 6 commits into
callstack:mainfrom
rjmreis:docs/landing-rework
Open

rjmreis wants to merge 6 commits into
callstack:mainfrom
rjmreis:docs/landing-rework

Conversation

@rjmreis

@rjmreis rjmreis commented Oct 9, 2026 •

Copy link
Copy Markdown

Motivation

The project has two sites: the marketing landing page at reactnativepaper.com and the documentation site on GitHub Pages. This replaces the documentation site's homepage with the landing page, so there is one site to maintain.

Per Satyajit's direction: swap the whole homepage for the landing page plus the docs navbar links, rather than merging the two pages' content. Refreshing the landing copy is deliberately out of scope — it was written by marketing and should be a separate task.

Related issue

Notion: Merge reactnativepaper.com + oss.callstack.com/react-native-paper

Screenshots / Videos

Walkthrough of the ported homepage — hero through footer, with the live demo driven through its Snackbar, dark theme and Material You states, and the testimonial slider.

rn-native-paper-small-2.mp4

Test plan

yarn docs generate:5x
yarn docs build
yarn docs preview

Open the site root and compare against https://reactnativepaper.com. Both the 5.x and 6.x homepages render the landing page, so any future version inherits it.

In the phone demo: the Sign me up button raises the Snackbar at the bottom of the screen, the Dark theme and Material You chips both toggle and change the demo's palette, and the Appbar's external-link icon opens the Appbar docs.

The docs footer artwork should still appear on other custom pages — /showcase/ is the one to check — and be suppressed only on the homepage.


How it was ported

The visual rules are lifted verbatim from the original's compiled linaria stylesheet into docs/src/css/landing-vendor.css, and the components mirror the original DOM so they can use those class names. docs/src/css/landing.css holds only the webfonts and the overrides needed because the docs preset styles headings, body *, pre/code and font synthesis with !important.

Needs a decision before merge

Platform Web. The original sets its headings in Platform Web, a Commercial Type retail face. The files here come from the source repo's src/fonts/PlatformWeb and carry "Not to be used for anything other than web font use!". That repo is private; this one is public, so merging redistributes the font to anyone who clones or forks. Whoever holds Callstack's licence with Commercial Type needs to confirm it covers both this repo and the domain the site is served from. If the answer is no, reverting is two files and the @font-face — the fallback chain already drops to Roboto.

New dependency. prism-react-renderer in the docs workspace. It is what the original uses, and nothing else reproduces its editor theme, line numbers and colouring.

Deployment

This is the first of two PRs. The second flips base from /react-native-paper/ to / and adds the CNAME, paired with the DNS move: custom domain set in the repo settings, Cloudflare records added DNS-only so GitHub can issue the certificate, then Enforce HTTPS, then re-proxy with SSL set to Full (strict). The ordering matters.

Ported from callstack-internal/paper-landing-page ahead of merging
reactnativepaper.com and oss.callstack.com/react-native-paper onto a
single domain.

Both versioned homepages become `pageType: custom` rendering a shared
<Landing /> component, so any future version picks up the same page.
Section order follows src/pages/index.js in the source: hero, numbers,
look and feel, Material You, code, key concepts, testimonials, Discord,
Callstack. The docs navbar is kept; the rspress feature grid, screenshot
gallery and Callstack home banner are removed rather than merged.

Stats and the GitHub star count stay live, via the same endpoints the
original uses. Roboto and Roboto Mono are vendored to match the
original's body and code type.

Headings are set in Platform Web on the original. That is a Commercial
Type retail face whose webfont licence is domain-scoped and does not
allow redistribution, so the file is not committed and headings fall
back to Roboto. landing.css documents how to restore it once the
licensing is settled.

The docs preset styles headings, `body *`, and `pre`/`code` with
!important, and disables weight synthesis via `font-synthesis: style`.
The landing scope overrides these so the page renders with the
original's metrics.

Two fixes to the source's snippet: `TouchableWithNativeFeedback` does
not exist, and its StyleSheet object was missing a comma.
Measured both pages element by element with Playwright instead of
comparing screenshots by eye, and corrected what differed.

Sizing, all of which had been guessed: the demo videos are capped at
297x630 to hold the movie ratio rather than filling their column, the
Material You art is 720px tall and positioned out of flow, the Material
Design badge renders at its natural 225x195, play badges are 60px,
testimonial avatars 60px, the Discord mark 175px and the Callstack
wordmark 300px.

Hero and Material You run flush with a 700px floor, and Numbers and Code
drop their bottom padding. These needed to outrank .landing-section,
whose padding shorthand in the 992px media query was winning on order.

Section headings take the font's natural leading, not the preset's 1.2.
Numbers keeps the 60px item margin the source never clears in row
layout. Key concepts' subtitle is body copy at 460px, not the 30px
tagline used by Code.

Restores the header band above the hero and the headings dropped from
Discord and Callstack, and reorders both to match the source.

Remaining gaps are tracked: the hero wraps to four lines rather than
three because Platform Web is absent for licensing reasons and Roboto
is wider, and testimonials render as a grid rather than the source's
slider.
Cap the code panel at the source's 400x400 scroll box, draw the phone
frame with object-fit: cover so the demo fills the real 320x710 cutout,
give the demo its Appbar so content clears the notch, and add the
ornament between the panel and the phone.

Port the footer section, which had been left out entirely.

Set the comparison panels in Roboto Mono with the source's line
padding, and take the editor column's heading and lede metrics from the
original.
Port the testimonial cards and their slider, add the footer section and the
Callstack wordmark, and render all three code panels through
prism-react-renderer so they carry the original's colours and line numbers.

Restore Platform Web for the headings, add Roboto Medium, and undo the preset
overrides that were reaching the page: heading margins, leading and weight,
letter-spacing, and the rules that leaked into the live demo.

Make the Material You chip switch palettes rather than sit inert, and stop the
docs footer artwork painting below the landing page.
@github-actions

github-actions Bot commented Oct 9, 2026 •

Copy link
Copy Markdown

Found potential problems with the pull request:

  • The description is too long. Please keep it under 1000 characters.

Drops the vendored Platform Web, which we cannot ship from a public repo,
and takes the face the rest of the docs site already uses.

Declares Alliance No. 2 here rather than relying on the theme: the copies
on assets.callstack.com are served without Access-Control-Allow-Origin,
so the theme's own declaration is CORS-blocked.

@satya164 satya164 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.

The CI workflow (lint, typecheck, tests) hasn't run on this PR yet, only the description check. It needs to pass before merge.

The "Needs a decision before merge" section in the description still talks about Platform Web, but the branch no longer ships it since the headings moved to Alliance. Can you update the description?

<Snackbar
visible={showSnack}
onDismiss={toggleSnack}
action={{ label: 'Dismiss', onPress: toggleSnack }}

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.

Pressing "Dismiss" leaves the Snackbar open. Snackbar calls action.onPress and then onDismiss on an action press, so toggleSnack runs twice and the state flips back to true.

onDismiss={() => setShowSnack(false)}
action={{ label: 'Dismiss', onPress: () => {} }}

@rjmreis rjmreis Oct 27, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in ed29ca7, exactly as you wrote it, onDismiss sets false and the action is a no-op. Verified on both the 5.x and 6.x homepages: the Snackbar now closes on Dismiss instead of flipping back.

color={isMaterialYou ? undefined : md2AppbarContent(isDarkTheme)}
icon="open-in-new"
onPress={() =>
void Linking.openURL(docsHref('docs/components/Appbar/'))

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.

docs/components/Appbar/ has no page, so this opens a 404. The build only has Appbar/Appbar, Appbar/AppbarAction etc. It also ignores the version, so on the 6.x homepage it opens the 5.x docs. LandingHero already handles this with getNextRoute.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in ed29ca7. It now points at /docs/components/Appbar/Appbar and goes through getNextRoute + withBase, same as LandingHero. Confirmed both /docs/components/Appbar/Appbar and /6.x/docs/components/Appbar/Appbar return 200 in the build.

Comment thread docs/5.x/_nav.json Outdated
"activeMatch": "^/docs/guides/"
},
{
"text": "Components",

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.

This and the docs/5.x/docs/_meta.json change are the output of generate-5x-docs.ts. #5094 removed these entries on purpose, and the deploy workflow regenerates them before building. In production this is a no-op, and locally without generate:5x it adds a Components link that 404s. Please revert both files.

function useGithubStars() {
const [stars, setStars] = useState<string>(() => {
try {
return localStorage.getItem('cachedGithubStars') ?? STARS_FALLBACK;

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.

Reading localStorage in the useState initializer causes a hydration mismatch. The prerendered HTML has 3000+, while the client's first render has the cached count on any repeat visit. Start from the fallback and read the cache in the effect.

@rjmreis rjmreis Oct 27, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in ed29ca7, state starts from STARS_FALLBACK and the cached value is read in the effect, so the prerendered HTML and the first client render agree.

const json = await response.json();

if (!cancelled) {
setData(json);

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.

The response is stored without checking response.ok or its shape. If the API returns a JSON error body, item.value is undefined and toLocaleString throws during render, which takes down the homepage.

The endpoint is also a deployment URL of the old landing page's Vercel project, which the domain move is meant to retire. The fallback numbers are outdated too (7371 stars, it's 14474 now).

@rjmreis rjmreis Oct 27, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in ed29ca7. Every response is now checked for response.ok and for the shape before use, with a per-field fallback, so a JSON error body can't take the homepage down.

I also dropped the Vercel endpoint rather than guarding it, since you're retiring it. It reads from public APIs instead, api.github.com for stars, api.npmjs.org for weekly downloads, and the commit total from the Link header's last page (Link is in GitHub's access-control-expose-headers, so it's readable cross-origin). The hero and the numbers band share one fetch. Fallbacks refreshed to current values.

preload="none"
ref={videoRef}
>
<source src={asset(`videos/${name}.webm`)} type="video/webm" />

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.

The WebM files are larger than the MP4s (3.4 MB vs 0.84 MB and 4.2 MB vs 1.9 MB), and listing WebM first makes browsers that support it download the larger one. Either swap the order or drop the WebM sources. material-you.png is also 3.1 MB and loads eagerly, which could use loading="lazy" or compression.

@rjmreis rjmreis Oct 27, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Fixed in ed29ca7, dropped the WebM sources and the two files (-7.9 MB).

material-you.png is 837 KB now, down from 3.1 MB: it was 2861x3709 but displays at 720px tall, so I resized it to exactly 2x that, and added loading="lazy". I also resized the two video posters on the same reasoning, shout if that's beyond what you wanted. About 10.9 MB off the repo in total.

export const asset = (path: string) => withBase(`/landing/${path}`);

/** An absolute URL to a page of this docs site, for links opened via Linking. */
export const docsHref = (path: string) =>

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.

react-native-web's Linking.openURL already resolves relative URLs with new URL(url, window.location), and the window check never matters since this only runs in onPress. withBase in LandingCode should be enough, and this helper can go.

@rjmreis rjmreis Oct 27, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Removed in ed29ca7, withBase in LandingCode is doing the work and the helper is gone.

Comment thread docs/src/css/landing.css Outdated

/* Testimonials render through a drag Slider in the source; these cards stand
in for it while keeping the original's proportions. */
.landing-testimonials {

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.

Nothing renders .landing-testimonials* anymore since the testimonials use the slider. The same goes for .tok-* further down. Both blocks and their comments can go.

src/assets/landing/dots.png and src/assets/landing/patterns/*.png are also unused, since the vendored CSS embeds the dot patterns as data URIs.

@rjmreis rjmreis Oct 27, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

All removed in ed29ca7, the .landing-testimonials* and .tok-* blocks, plus dots.png and patterns/*.png. Confirmed nothing referenced them first.

Comment thread docs/src/css/landing.css Outdated
src: url('../assets/landing/fonts/roboto-mono-400.woff2') format('woff2');
}

/* typography.css in the original: Roboto body, Alliance for h1/h2. */

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.

This comment doesn't belong to anything, the rule it describes is further down.

@rjmreis rjmreis Oct 27, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Gone, along with the rest of the comments in this file, since you asked for the LLM-written ones to go. landing.css has none left.

Two exceptions I'd rather check than guess at: a one-line "generated, do not hand-edit" marker on landing-vendor.css, and two empty-catch comments in LandingHero that the repo's own no-empty rule fails without. Say the word if you want those gone too.

Comment thread docs/theme/index.tsx
import { Layout as BasicLayout } from '@rspress/core/dist/theme/index.js';

import Outline from './Outline';
import PaperHomeShowcase from '../src/components/PaperHomeShowcase';

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.

With this removed, docs/src/components/PaperHomeShowcase.tsx and docs/public/images/home/*.svg are unused. Can you delete them too?

@rjmreis rjmreis Oct 27, 2026 •

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Deleted both in ed29ca7, PaperHomeShowcase.tsx and the six docs/public/images/home/*.svg files.

Use the docs theme's own fonts instead of declaring Roboto and Alliance
here, which applied to every page and shifted the layout on load.

Fix the Snackbar dismiss, the versioned Appbar and Docs links, the Paper 6
snippet, and keyboard access to the slider, videos and calls to action.
Validate the stats responses and read them from public APIs rather than the
old landing page's Vercel deployment.

Revert the generated 5.x nav files and drop unused assets.
@rjmreis
rjmreis requested a review from satya164 October 27, 2026 08:05
@rjmreis
rjmreis marked this pull request as ready for review October 27, 2026 08:06
Copilot AI balanced review requested due to automatic review settings October 27, 2026 08:06

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🟡 Changes recommended

Unresolved interaction and accessibility defects affect the testimonial carousel and the demo’s documentation action.

3 open issues
What changed in this PR

Replaces the documentation homepage with the marketing landing page, consolidating both sites while retaining documentation navigation for 5.x and 6.x.

Changes:

  • Adds shared landing sections, interactive demos, testimonials, and live project statistics.
  • Ports landing styles and artwork, with overrides for the documentation theme.
  • Adds syntax highlighting and removes the previous homepage showcase and icons.
File Description
yarn.lock Locks the syntax-highlighting dependency.
docs/​theme/​index.tsx Removes the previous homepage additions.
docs/​src/​css/​landing.css Adapts landing styles to the docs theme.
docs/​src/​css/​landing-vendor.css Adds compiled landing-page styles.
docs/​src/​css/​custom.css Imports landing styles.
docs/​src/​components/​PaperHomeShowcase.tsx Removes the previous showcase.
docs/​src/​components/​landing/​stats.ts Loads project statistics with fallbacks.
docs/​src/​components/​landing/​LandingTestimonials.tsx Adds testimonial cards.
docs/​src/​components/​landing/​LandingSlider.tsx Adds carousel navigation and swiping.
docs/​src/​components/​landing/​LandingSection.tsx Shares section layouts and asset paths.
docs/​src/​components/​landing/​LandingNumbers.tsx Displays project statistics.
docs/​src/​components/​landing/​LandingMaterialYou.tsx Adds the Material You section.
docs/​src/​components/​landing/​LandingLookAndFeel.tsx Adds playable demonstration videos.
docs/​src/​components/​landing/​LandingHero.tsx Adds the hero and version-aware docs link.
docs/​src/​components/​landing/​LandingFooter.tsx Adds landing-page footer links.
docs/​src/​components/​landing/​LandingDiscord.tsx Adds the community invitation.
docs/​src/​components/​landing/​LandingConcepts.tsx Presents core library features.
docs/​src/​components/​landing/​LandingCodeSnippet.tsx Renders highlighted code examples.
docs/​src/​components/​landing/​LandingCode.tsx Adds code comparisons and the themed demo.
docs/​src/​components/​landing/​LandingCallstack.tsx Adds the Callstack section.
docs/​src/​components/​landing/​LandingButton.tsx Shares styled call-to-action links.
docs/​src/​components/​landing/​LandingBanner.tsx Adds the introductory contact banner.
docs/​src/​components/​landing/​index.tsx Assembles the shared landing page.
docs/​src/​components/​landing/​editorTheme.ts Defines syntax-highlighting colors.
docs/​src/​components/​landing/​cssVars.ts Types CSS custom properties.
docs/​public/​landing/​images/​ornament-small.svg Adds decorative artwork.
docs/​public/​landing/​images/​material-badge.svg Adds the Material Design badge.
docs/​public/​landing/​images/​icons/​twitter.svg Adds the testimonial source icon.
docs/​public/​landing/​images/​icons/​theming-icon.svg Illustrates theming support.
docs/​public/​landing/​images/​icons/​star-icon.svg Illustrates repository stars.
docs/​public/​landing/​images/​icons/​play.svg Adds the video play icon.
docs/​public/​landing/​images/​icons/​platform-icon.svg Illustrates platform support.
docs/​public/​landing/​images/​icons/​paper-white.svg Adds footer branding.
docs/​public/​landing/​images/​icons/​live-icon.svg Illustrates the live demo.
docs/​public/​landing/​images/​icons/​download-icon.svg Illustrates download statistics.
docs/​public/​landing/​images/​icons/​discord.svg Adds community branding.
docs/​public/​landing/​images/​icons/​commit-icon.svg Illustrates commit statistics.
docs/​public/​landing/​images/​icons/​callstack.svg Adds footer attribution artwork.
docs/​public/​landing/​images/​icons/​callstack-dark.svg Adds Callstack section branding.
docs/​public/​landing/​images/​icons/​accessibility-icon.svg Illustrates accessibility support.
docs/​public/​landing/​images/​google-play.svg Adds the Android download badge.
docs/​public/​landing/​images/​finger.svg Adds pointing-hand artwork.
docs/​public/​landing/​images/​arrow-right.svg Adds the next-slide arrow.
docs/​public/​landing/​images/​arrow-left.svg Adds the previous-slide arrow.
docs/​public/​landing/​images/​appstore.svg Adds the iOS download badge.
docs/​public/​images/​home/​versions.svg Removes the previous versioning icon.
docs/​public/​images/​home/​palette.svg Removes the previous theming icon.
docs/​public/​images/​home/​moon.svg Removes the previous dark-mode icon.
docs/​public/​images/​home/​devices.svg Removes the previous platform icon.
docs/​public/​images/​home/​components.svg Removes the previous components icon.
docs/​public/​images/​home/​accessibility.svg Removes the previous accessibility icon.
docs/​package.json Adds prism-react-renderer.
docs/​6.x/​index.mdx Uses the shared landing page.
docs/​5.x/​index.mdx Uses the shared landing page.

Review effort: Balanced

/>
<Appbar.Action
color={isMaterialYou ? undefined : md2AppbarContent(isDarkTheme)}
icon="open-in-new"
Comment on lines +163 to +164
.awvlien{-webkit-align-items:center;align-items:center;background:transparent;display:none;height:100%;left:0;margin-left:auto;margin-right:auto;position:absolute;right:0;top:0;width:350px}
@media (min-width:650px){.awvlien{display:-webkit-flex;display:flex;width:630px}}
Comment thread docs/src/css/landing.css
Comment on lines +273 to +279
.landing .awvlien button {
padding: 0;
border: 0;
background: none;
cursor: pointer;
line-height: 0;
}

This branch has not been deployed

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants