Routing Fundamentals in Nextjs
Tags: webdev, programming, tutorial, nextjs
Published: 2023-07-29 10:31:22

Routing is a crucial aspect of web applications as it determines how users navigate through different pages. Nextjs with its robust capabilities not only simplifies the development process but it also optimizes your application for better user experience.

## Terminology

- **Routing:** The mechanism by which the application handles navigation and determines what content to display based on the url or the user's interaction with the interface.

- **Tree:**  It is a hierarchical structure representation of the entire routing system.

- **Subtree:** A smaller hierarchical structure within the main tree and it has its own starting point or root from which different pages can be accessed.

- **Root:**  Starting point of the tree or subtree and it is associated with the root url ("/").

- **Leaf:**  A page that does not have any child pages, it is the end or terminal node in the page tree or subtree.

- **url segment:**  Part of the url path delimited by slashes.

- **url path:**  Part of the url that comes after the domain.

## Creating Routes
Nextjs uses a file system based router where folders are used to define the routing system and files are used to create the user interface that is shown for a route segment. Each folder in a route represents a route segment and each route segment corresponds to a specific page in the application.

## Pages and Layout
A page is a UI that is unique to a route. It is always the leaf of the route subtree, it is required to make a route segment publicly accessible.

```
export default function Page() {
  return <h1>Hello, Home page!</h1>
}
```
A layout is a UI that is shared between multiple pages. You can define a layout file by exporting a react component and the component should accept a children prop.

The children prop is of type React.ReactNode which means it receives valid react elements or components as its value. The root layout applies to all routes and must contain html and body tags.

```
export default function RootLayout({
  children,
}: {
  children: React.ReactNode
}) {
  return (
    <html lang="en">
      <body>{children}</body>
    </html>
  )
}
```
Layouts defined inside a folder eg:(app/dashboard/layout.tsx) applies to the dashboard route segment. The layout will be shared across all pages in that route segement.

```
export default function DashboardLayout({
  children, // will be a page or nested layout
}: {
  children: React.ReactNode
}) {
  return (
    <section>
      {/* Include shared UI here e.g. a header or sidebar */}
      <nav></nav>
 
      {children}
    </section>
  )
}
```

## Linking and Navigating
The Nextjs app router uses [server-centric routing](https://nextjs.org/docs/app/building-your-application/routing#server-centric-routing-with-client-side-navigation) in that the client does not have to download a route map and the router uses client side navigation with the link component. There are two ways to navigate between routes; link component and useRouter() hook.

### Link component
It is a react component that extends the html anchor tag and it is the primary way to navigate between routes in Nextjs.

```
import Link from 'next/link'
 
export default function Page() {
  return <Link href="/dashboard">Dashboard</Link>
}
```

### useRouter Hook
[useRouter](https://nextjs.org/docs/app/api-reference/functions/use-router) hook allows you to programmatically change routes inside client components. It means that you can use Javascript code to control the navigation behavior rather than relying on traditional anchor tags or browser's navigation buttons. By using the useRouter hook you can change the url and navigate the user to a different page based on specific conditions, events or user interactions.

```
'use client'
 
import { useRouter } from 'next/navigation'
 
export default function Page() {
  const router = useRouter()
 
  return (
    <button type="button" onClick={() => router.push('/dashboard')}>
      Dashboard
    </button>
  )
}
```

## Dynamic Routes
Dynamic data refers to data that is not known or fixed at the time of defining routes eg; user-generated content, data fetched from an external API or data stored in a database.

Dynamic segments allow you to handle such dynamic data and create routes based on it, when you have routes that depend on dynamic data, you may not know the exact segment names ahead of time instead you want to generate routes based on the actual data that is available during runtime or at buildtime.

A [dynamic segment](https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes) can be created by wrapping a folder name in square brackets [foldername] and are passed as the params props to layout, page, route and generateMetadata functions.

```
export default function Page({ params }: { params: { slug: string } }) {
  return <div>My Post: {params.slug}</div>
}
```

## Parallel Routes
[Parallel routes](https://nextjs.org/docs/app/building-your-application/routing/parallel-routes) allow you to render one or more pages in the same layout. They are defined with @folder and are passed to the same level layout as props.

```
export default function Layout(props: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {props.children}
      {props.team}
      {props.analytics}
    </>
  )
}
```

## Intercepting Routes
[Intercepting routes](https://nextjs.org/docs/app/building-your-application/routing/intercepting-routes) allow you to load a route within the current layout while keeping the context of the current page and are defined with the (...) convention.

- (.) matches segments on the same level.

- (..) matches segments one level above.

- (..)(..) matches segments two levels above.

- (...) matches segments from the root app directory.

## Route Handlers
Nextjs 13 introduced a new approach of building API's in the app router.
[Route handlers](https://nextjs.org/docs/app/building-your-application/routing/router-handlers) are functions executed when users access site routes. They are responsible for handling HTTP requests and responses for routes in your application.

When a user visits a particular page or url in a Nextjs application, the corresponding route handler handles the request created by the user and returns the appropriate response thereby rendering desired content.

Nextjs extends nextRequest and nextResponse with web request and web response. There cannot be a route.js file at the same route as page.js.

### Conclusion
The blog post provides a comprehensive overview of the essential concepts related to routing in the Nextjs famework. The post begins by explaining how routing enables navigation between different pages.