Skip to main content

Basic pages

app/
  page.tsx          # /
  about/page.tsx    # /about
  blog/page.tsx     # /blog
A page exports a default React component:
// app/page.tsx
export default function Home() {
  return <h1>Welcome</h1>;
}

Layouts

Layouts wrap pages and persist across navigation. Create layout.tsx at any level:
// app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html>
      <body>{children}</body>
    </html>
  );
}
Nested layouts compose automatically:
app/
  layout.tsx            # Wraps everything
  page.tsx              # /
  dashboard/
    layout.tsx          # Wraps dashboard pages
    page.tsx            # /dashboard
    settings/page.tsx   # /dashboard/settings
/dashboard/settings renders inside both the root layout and the dashboard layout.

Dynamic routes

Use brackets for dynamic segments:
app/
  blog/[slug]/page.tsx      # /blog/:slug
  users/[id]/page.tsx       # /users/:id
Access params via the usePageContext hook:
// app/blog/[slug]/page.tsx
'use client'
import { usePageContext } from "veryfront/context";

export default function BlogPost() {
  const { params } = usePageContext();
  return <h1>Post: {params.slug}</h1>;
}

Catch-all routes

Use [...segments] to match multiple path segments:
app/docs/[...segments]/page.tsx   # /docs/a, /docs/a/b, /docs/a/b/c

MDX pages

Rename any page to .mdx to write content in Markdown with JSX:
{/* app/about/page.mdx */}

# About Us

We build tools for developers.

<TeamGrid members={team} />
MDX pages support frontmatter:
---
title: "About"
description: "Learn about our team."
---

# {frontmatter.title}
Access frontmatter from components using usePageContext() from veryfront/context:
'use client'
import { usePageContext } from "veryfront/context";

function PageTitle() {
  const { frontmatter } = usePageContext();
  return <h1>{frontmatter.title}</h1>;
}

Client components

By default, components render on the server. Add 'use client' to make a component interactive:
'use client'

import { useState } from "react";

export default function Counter() {
  const [count, setCount] = useState(0);
  return <button onClick={() => setCount(count + 1)}>Count: {count}</button>;
}
Use the Link component for client-side navigation:
import { Link } from "veryfront/router";

export default function Nav() {
  return (
    <nav>
      <Link href="/">Home</Link>
      <Link href="/about">About</Link>
    </nav>
  );
}
Programmatic navigation:
'use client'

import { useRouter } from "veryfront/router";

export default function LoginForm() {
  const router = useRouter();

  async function handleSubmit() {
    await login();
    router.push("/dashboard");
  }

  return <form onSubmit={handleSubmit}>...</form>;
}

Next