Hola 🇪🇸,
I'm Akash Hamirwasia

I'm from Bangalore, India 🇮🇳
Frontend Engineer at ElevenLabs
I love building products on the web ✨
My newest product
slantit.app
Twitter, GitHub@blenderskoolWebsiteakashhamirwasia.com

Remember static sites?

akashhamirwasia.com React Alicante 2024

Remember static sites?

index.tsxabout.tsx
bg-blue-600text-center
Button.tsx Header.tsx
akashhamirwasia.com React Alicante 2024
akashhamirwasia.com React Alicante 2024
akashhamirwasia.com React Alicante 2024
akashhamirwasia.com React Alicante 2024

How do we show dynamic data on the UI?

1. APIs and fetch()

2. Fetch data before UI is sent to the client

akashhamirwasia.com React Alicante 2024

2. Fetch data before UI is sent to the client

Data fetching
akashhamirwasia.com React Alicante 2024
GithubSponsors.tsx
function GithubSponsors({ sponsors }) {
  return (
    <div>
      <h1>If you like what I build, sponsor my work</h1>
      <ul>
        {sponsors.map((sponsor) => (
          <li key={sponsor.id}>
            <img src={sponsor.avatar_url} />
          </li>
        ))}
      </ul>
      <p>Join {sponsors.length} people to support my open source work.</p>
    </div>
  );
}
akashhamirwasia.com React Alicante 2024
projects.tsx
function Projects({ sponsors }) {
return (
<div>
{/* ... */}
<GithubSponsors sponsors={sponsors} />
{/* ... */}
</div>
);
}
akashhamirwasia.com React Alicante 2024

2. Fetch data before UI is sent to the client

Data fetching
export const getStaticProps = async () => ...;
export const query = graphql`query { ... }`;
Route level only
akashhamirwasia.com React Alicante 2024
akashhamirwasia.com React Alicante 2024
GithubSponsors.tsx
function GithubSponsors({ sponsors }) {
return (
<div>
<h1>If you like what I build, sponsor my work</h1>
<ul>
{sponsors.map((sponsor) => (
<li key={sponsor.id}>
<img src={sponsor.avatar_url} />
</li>
))}
</ul>
<p>Join {sponsors.length} people to support my open source work.</p>
</div>
);
}
akashhamirwasia.com React Alicante 2024
projects.tsx
function Projects() {
  return (
    <div>
      {/* ... */}
      <GithubSponsors />
      {/* ... */}
    </div>
  );
}
[post].tsx
function BlogPost() {
  return (
    <div>
      {/* ... */}
      <GithubSponsors />
      {/* ... */}
    </div>
  );
}
akashhamirwasia.com React Alicante 2024

useStaticQuery();

Component level data-fetching.
Co-location of data-fetching and UI in a component.
It cannot accept variables. It has to be a "static" query.
Only one occurrence of the hook in a file.
Data fetching by static analysis
akashhamirwasia.com React Alicante 2024

Can we do better?

akashhamirwasia.com React Alicante 2024

What if React itself handled data fetching before rendering the UI?

akashhamirwasia.com React Alicante 2024

React Server Components?

akashhamirwasia.com React Alicante 2024

Static site

Build
Server
Client
JS
Blog posts
HTML
JS
HTML
Ready
JS
akashhamirwasia.com React Alicante 2024

Static site is a frozen snapshot of a Server rendered site!

akashhamirwasia.com React Alicante 2024

If RSCs can be used in Server rendered sites, they can be used for Static sites too!

akashhamirwasia.com React Alicante 2024

With React Server Components

GithubSponsors.tsx
function GithubSponsors() {
const { sponsors } = useStaticQuery(graphql`
query {
...
}
`);

return (
<div>
<h1>If you like what I build, sponsor my work</h1>
{/* ... */}
</div>
);
}
akashhamirwasia.com React Alicante 2024
<!DOCTYPE html><html lang="en"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" href="/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2" as="font" crossorigin="" type="font/woff2"/><link rel="stylesheet" href="/_next/static/css/02ba055114f14ef8.css" data-precedence="next"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/webpack-d0ceac4fb78a3613.js"/><script src="/_next/static/chunks/fd9d1056-2821b0f0cabcd8bd.js" async=""></script><script src="/_next/static/chunks/23-2309b8fd26fbddcb.js" async=""></script><script src="/_next/static/chunks/main-app-15aa97dceccc8824.js" async=""></script><title>Create Next App</title><meta name="description" content="Generated by create next app"/><link rel="icon" href="/favicon.ico" type="image/x-icon" sizes="16x16"/><meta name="next-size-adjust"/><script src="/_next/static/chunks/polyfills-78c92fac7aa8fdd8.js" noModule=""></script></head>
<body class="__className_aaf875"><main>
  <div><h2>Sponsor <!-- -->blenderskool<!-- -->&#x27;s work.</h2><div><ul>
  <li><img src="https://avatars.githubusercontent.com/u/30949385?s=60&amp;v=4" alt="saurabhdaware"/></li>
  <li><img src="https://avatars.githubusercontent.com/u/19529592?s=60&amp;v=4" alt="shivaylamba"/></li>
  <li><img src="https://avatars.githubusercontent.com/u/6796491?s=60&amp;v=4" alt="animysore"/></li></ul>
  <p>Join <!-- -->5<!-- --> people to support <!-- -->blenderskool<!-- -->&#x27;s open source work.</p></div></div>

  <div><h2>Sponsor <!-- -->antfu<!-- -->&#x27;s work.</h2><div><ul>
  <li><img src="https://avatars.githubusercontent.com/u/2841780?s=60&amp;v=4" alt="AnandChowdhary"/></li>
  <li><img src="https://avatars.githubusercontent.com/u/34610289?s=60&amp;v=4" alt="MichaelGitArt"/></li>
  <li><img src="https://avatars.githubusercontent.com/u/1875256?s=60&amp;v=4" alt="bushuai"/></li></ul>
  <p>Join <!-- -->782<!-- --> people to support <!-- -->antfu<!-- -->&#x27;s open source work.</p></div></div>
</main><script src="/_next/static/chunks/webpack-d0ceac4fb78a3613.js" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0]);self.__next_f.push([2,null])</script><script>self.__next_f.push([1,"1:HL[\"/_next/static/media/c9a5bc6a7c948fb0-s.p.woff2\",\"font\",{\"crossOrigin\":\"\",\"type\":\"font/woff2\"}]\n2:HL[\"/_next/static/css/02ba055114f14ef8.css\",\"style\"]\n"])</script><script>self.__next_f.push([1,"3:I[5751,[],\"\"]\n7:I[9275,[],\"\"]\n8:I[1343,[],\"\"]\na:I[6130,[],\"\"]\nb:[]\n0:
[[[\"$\",\"link\",\"0\",{\"rel\":\"stylesheet\",\"href\":,
akashhamirwasia.com React Alicante 2024

Not just limited to data fetching

akashhamirwasia.com React Alicante 2024

We can do any build-time processing that we don't want the client to do

akashhamirwasia.com React Alicante 2024

Code Highlighting with shiki

import { getHighlighter } from 'shiki';

async function CodeBlock({ code, language }) {
  const highlighter = await getHighlighter({
    themes: ['github-light', 'tokyo-night'],
  });

  const html = await highlighter.codeToHtml(code, {
    lang: language,
    themes: {
      dark: 'tokyo-night',
      light: 'github-light',
    },
  });

  return (
    <div>
      <div dangerouslySetInnerHTML={{ __html: html }} />
    </div>
  );
}
akashhamirwasia.com React Alicante 2024

Advantages of RSCs in static sites

Component level data-fetching.
Co-location of data-fetching and UI in a component.
Can have dynamic queries that make use of props.
Not just limited to data-fetching, any processing can be done.
Theoretically does not require any client-side JS and hydration at all!
Portable to any other React framework.
akashhamirwasia.com React Alicante 2024

How can I use RSCs for my static site?

akashhamirwasia.com React Alicante 2024

akashhamirwasia.com React Alicante 2024
akashhamirwasia.com React Alicante 2024

Making Sense of React Server Components

Josh W Comeau

React for Two Computers

Dan Abramov

akashhamirwasia.com React Alicante 2024

Gracias!

Twitter, GitHub@blenderskoolEmail[email protected]Websiteakashhamirwasia.com
akashhamirwasia.com React Alicante 2024
1 / 33
Slides Overview