Domů O mně Služby Portfolio Učím Blog Kontakt
← Zpět na učím

05 — Layout komponenty (layout.js / layout.tsx)

Výuka

Proč to existuje?

Když vytváříš webovou aplikaci, mnoho stránek sdílí stejné prvky — header, footer, navigaci, sidebar. Bez layoutů bys musel tyto části kopírovat do každé stránky zvlášť. Layouty umožňují tyto části napsat jednou a sdílet mezi více stránkami.

Navíc layouty uchovávají stav komponent při navigaci — pokud máš v layoutu otevřené menu nebo komponentu s interaktivním stavem, zůstane zachovaná, když uživatel přechází mezi stránkami.

Co je layout?

Layout není stránka — layout obaluje stránky. Je to React komponenta, která přijímá children prop (to jsou stránky uvnitř) a může k nim přidat společné UI prvky.

Představ si to jako rámeček obrazu: rám (layout) zůstává stejný, ale obrázek uvnitř (page) se mění podle toho, na jaké stránce jsi.

Jak to funguje?

V Next.js existují dva typy layoutů:

1. Root layout (app/layout.js)

  • Je povinný a musí obsahovat a tagy
  • Obaluje celou aplikaci
  • Slouží pro globální prvky (hlavní navigace, footer)

2. Vnořené layouty (např. app/blog/layout.js)

  • Jsou volitelné
  • Obalují pouze stránky v dané složce a podsložkách
  • Slouží pro sekce aplikace (např. blog se sidebar, dashboard s navigací)

K čemu to slouží?

  • Lepší organizace UI — sdílené prvky (header, footer) jsou na jednom místě
  • DRY princip — nepotřebuješ opakovat stejný kód
  • Zachování stavu — interaktivní komponenty v layoutu zůstávají "živé" při navigaci
  • Rychlé vytváření sekcí — blog sekce může mít sidebar, admin sekce může mít jinou navigaci

JavaScript

// app/layout.js (root layout)
export default function RootLayout({ children }) {
  return (
    <html lang="cs">
      <body>
        <header>
          <nav>
            <a href="/">Domů</a>
            <a href="/blog">Blog</a>
          </nav>
        </header>
        <main>{children}</main>
        <footer>© Moje učebnice</footer>
      </body>
    </html>
  )
}

// app/page.js (index page)
export default function Page() {
  return <h1>Vítejte — Next.js App Router</h1>
}

// app/blog/layout.js (vnořený layout pro blog)
export default function BlogLayout({ children }) {
  return (
    <div style={{display: 'flex'}}>
      <aside style={{width: 200}}>
        <h3>Blog Sidebar</h3>
        <ul>
          <li><a href="/blog">Všechny články</a></li>
          <li><a href="/blog/kategorie">Kategorie</a></li>
        </ul>
      </aside>
      <main style={{flex: 1}}>{children}</main>
    </div>
  )
}

TypeScript

// app/layout.tsx (root layout)
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="cs">
      <body>
        <header>
          <nav>
            <a href="/">Domů</a>
            <a href="/blog">Blog</a>
          </nav>
        </header>
        <main>{children}</main>
        <footer>© Moje učebnice</footer>
      </body>
    </html>
  )
}

// app/page.tsx (index page)
export default function Page(): JSX.Element {
  return <h1>Vítejte — Next.js App Router</h1>
}

// app/blog/layout.tsx (vnořený layout pro blog)
export default function BlogLayout({ children }: { children: React.ReactNode }) {
  return (
    <div style={{display: 'flex'}}>
      <aside style={{width: 200}}>
        <h3>Blog Sidebar</h3>
        <ul>
          <li><a href="/blog">Všechny články</a></li>
          <li><a href="/blog/kategorie">Kategorie</a></li>
        </ul>
      </aside>
      <main style={{flex: 1}}>{children}</main>
    </div>
  )
}

Rozdíl JS vs TS

TypeScript zajišťuje typovou kontrolu pro children, params a další props (např. ({ children }: { children: React.ReactNode })). To pomáhá vyhnout se chybám při refaktoringu — pokud změníš strukturu props, TypeScript ti ihned ukáže, kde je potřeba aktualizovat kód.

Důležité poznámky

use client direktiva

Layouty jsou ve výchozím nastavení server components. Pokud potřebuješ klientskou logiku (state, event handlery, hooks), označ soubor direktivou "use client" na začátku:

"use client"

import { useState } from 'react'

export default function InteractiveLayout({ children }) {
  const [isOpen, setIsOpen] = useState(false)
  // ... klientská logika
}

Tip

Přehled vnořených layoutů — ASCII diagram

Příklad, jak se mohou vnořené layouty a stránky navzájem vztahovat:

app/
├─ layout.tsx          # root layout (html + body + hlavní navigace)
├─ page.tsx            # → /
├─ blog/
  ├─ layout.tsx       # blog layout (sidebar s kategoriemi)
  ├─ page.tsx         # → /blog
  └─ [slug]/
     └─ page.tsx      # → /blog/:slug
└─ dashboard/
   ├─ layout.tsx       # dashboard layout (auth wrapper + admin nav)
   ├─ page.tsx         # → /dashboard
   └─ analytics/
      ├─ layout.tsx    # nested layout pro analytics (grafy toolbar)
      └─ page.tsx      # → /dashboard/analytics

Jak se vnořování projevuje:

  • Když navštívíš /blog/prvni-clanek, Next.js vykreslí:
    1. Root layout (html + body + hlavní navigace)
    2. Blog layout (sidebar)
    3. Page pro článek

Vnořené layouty přidávají nebo mění části UI pouze pro daný segment, a stav v root layoutu zůstává zachován při navigaci mezi podstránkami.

Kvíz

Který soubor sdílí UI mezi stránkami v rámci jedné sekce aplikace?

layout.js obalí všechny stránky v daném segmentu (složce) a ukládá sdílené části UI jako header, footer nebo sidebar. Na rozdíl od page.js, který je specifický pro jednu URL, layout se aplikuje na celou sekci aplikace.

🎯 Závěrečný projekt

Po dokončení všech 8 dílů vytvoříte jednoduchou Todо aplikaci v čistém JavaScriptu. Naučíte se, jak aplikovat vše, co jste se naučili, na reálný projekt.

Zobrazit podrobnosti projektu →

Připraveni začít?

Zaregistrujte se a získejte přístup ke všem dílům tohoto seriálu

Kontaktujte mě

Informace o seriálu

Obtížnost

Délka

Cca 480 minut

Počet videí

8 videí + projekty

Certifikát

Po dokončení obdržíte certifikát


Lekce v této sekci


Struktura lekcí (souborový strom)

06. Typescript specifika
  • v přípravě
08. Moduly tridy
  • v přípravě
09. React zaklady
  • v přípravě
10. React hooks
  • v přípravě
12. Nextjs server
  • v přípravě
13. Databaze auth
  • v přípravě
14. Nextjs pokrocile
  • v přípravě