Async Server Components

Components That Await

A Server Component can be an async function. You await data right inside it: no useEffect, no loading state, no API layer just for your own UI.

app/products/page.tsx

type Product = { id: number; name: string; price: number; stock: number };

async function getProducts(): Promise<Product[]> {
  const res = await fetch('https://api.shopease.in/products', { cache: 'force-cache' });
  if (!res.ok) throw new Error('Failed to load products: ' + res.status);
  return res.json();
}

export default async function ProductsPage() {
  const products = await getProducts();
  return (
    <ul>
      {products.map((p) => (
        <li key={p.id}>
          {p.name} — ₹{p.price} {p.stock === 0 && <em>(out of stock)</em>}
        </li>
      ))}
    </ul>
  );
}

Compared With the Client Way

Client Component + useEffectAsync Server Component
RequestsBrowser → your API → databaseServer → database (one hop)
First HTMLSpinnerReal content
SecretsNeed an API in betweenUsed directly, never exposed
JS shippedComponent + fetch logicNone

How React Renders It

request /products
   │
   ▼
React renders the tree on the server
   ├─ <Layout>        (sync)
   └─ <ProductsPage>  (async)  ── await getProducts() ──► data
   │
   ▼
HTML + RSC payload streamed to the browser
   │
   ▼
Browser shows HTML, hydrates only Client Components