Next.js 13 Crash Course

Arnav SinghArnav Singh
3 min read

The New App Directory

  • Now you are supposed to define the route in the app directory rather than the pages directory

  • Now in every route directory, you can define the following files

    • layout.js → Describes the HTML structure of the route

    • page.js → Defines the component of that route

    • head.js → Here you can define the head tag. This will be automatically injected in layout.js

    • error.js → You can define a fallback component in case of error

    • loading.js → Fallback component when the component is loading

  • If you want to create a route /about then you will have to create a folder called about and inside it you will have to create a file called page.js all the other files are optional.

Layout.js

  • You can define the HTML structure of a route using layout.js

    • It is used to describe the HTML structure of the page

    • There is a root layout file that is required, it should not be deleted

    • If you want to define the HTML structure of /dashboard/stat then you can define it in the following locations

      • root

      • /dashboard

      • /stat

New Font feature

  • Previously, the fonts were not bundled with the application, so the application had to request the CDN to load the font when loading the site.

  • Now fonts can be bundled with the application. So, no more additional requests for fonts, making the website load faster.

  • Note → You are supposed to do this import in layout.js

Image

  • If you are importing an image from another website you must mention that domain in next.config.js for optimization purposes

Data Fetching

  • getStaticProp and getServersideProp have been removed next.js 13. Now you can directly use fetch function.

  • You might be wondering, what if this component has some state and it re-renders, then fetch will be called twice? Well no!

    • Next.js 13 has two types of components, serverside & clientside component

      • serverside component

        • Here, you can’t use any frontend features of JS like useEffect and onClick

        • This is designated by the absence of use client string at the top of the file

      • Client-side component

    • You can notice the absence use client

  • So, you are supposed to do data fetching in a serverside component and then you import a client-side component inside a serverside component and pass the fetched data to the client-side component

  • Server-side Rendering (Dynamic Rendering), Static Generation & Incremental Static Regeneration

    • Static (Default)

      • Page is generated at build time
    • Dynamic

      • The page is generated at run time

          fetch(URL,{cache:"no-store"})
          //or
          fetch(URL,{revalidate: 0})
        
        • Using cookies() or headers() in a Server Component will opt the whole route into dynamic rendering at request time.
    • Revalidate

        fetch(URL,{revalidate: n})
      
      • the cache expires every n seconds

Data Fetching without fetch()

import prisma from './lib/prisma';

export const revalidate = 3600; // revalidate every hour

async function getPosts() {
  const posts = await prisma.post.findMany();
  return posts;
}

export default async function Page() {
  const posts = await getPosts();
  // ...
}

Read params in serverside components

How to add styled-components with next.js 13

  • create a file called lib/registry.tsx

      'use client';
    
      import React, { useState } from 'react';
      import { useServerInsertedHTML } from 'next/navigation';
      import { ServerStyleSheet, StyleSheetManager } from 'styled-components';
    
      export default function StyledComponentsRegistry({
        children,
      }: {
        children: React.ReactNode;
      }) {
        // Only create stylesheet once with lazy initial state
        // x-ref: <https://reactjs.org/docs/hooks-reference.html#lazy-initial-state>
        const [styledComponentsStyleSheet] = useState(() => new ServerStyleSheet());
    
        useServerInsertedHTML(() => {
          const styles = styledComponentsStyleSheet.getStyleElement();
          styledComponentsStyleSheet.instance.clearTag();
          return <>{styles}</>;
        });
    
        if (typeof window !== 'undefined') return <>{children}</>;
    
        return (
          <StyleSheetManager sheet={styledComponentsStyleSheet.instance}>
            {children}
          </StyleSheetManager>
        );
      }
    
  • Inside of app/layout.tsx import the previously created file

      import StyledComponentsRegistry from './lib/registry';
    
      export default function RootLayout({ children }: { children: React.ReactNode }) {
        return (
          <html>
            <body>
              <StyledComponentsRegistry>{children}</StyledComponentsRegistry>
            </body>
          </html>
        );
      }
    
1
Subscribe to my newsletter

Read articles from Arnav Singh directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

Arnav Singh
Arnav Singh

Student . Programmer . 3D Artist . Game Developer