Skip to content

Instantly share code, notes, and snippets.

@misostack
Last active June 19, 2024 13:25
Show Gist options
  • Save misostack/85b1a85212257d0d2a006a381198488e to your computer and use it in GitHub Desktop.
Save misostack/85b1a85212257d0d2a006a381198488e to your computer and use it in GitHub Desktop.
NextJS Cheatsheet

NextJS CheatSheet

npx create-next-app seo --use-yarn --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter"

Overview Architecture

image

Main Concept

Development vs Production

Development stage: TypeScript and ESLint integration, Fast Refresh, ...

Production stage: Compiled, Bundled, Minified and Code Split

image

Compiled : JSX -> should be transformed to JS version that browser can understand

image

NestJS use SWC to replace Babel as a compiled tool.

Minifying: Removed unnessary code formatting and comments without changing the code's functionality

image

Bundled: Resolved the web of dependencies(packages) and merging the files(modules) into optimized bundled for browser, the goal is reducing the number of requests for files when user visit a web page

image

Code Splitting: Splitting the application's bundle into smaller chunks required by each entry point ( page URL ). The goal is reducing the initial time for the app - only loading the code required to run that page:

  • Shared Code between pages
  • Preloading Code
  • Dynamic Imports

image

BuildTime vs Runtime

BuildTime: is giving name for a series of steps that transform application's code into production-optimized files to be deployed on server and consumed by users includes:

  • HTML Files for static generated pages
  • Javascript code for rendering pages on the server
  • JavaScript code for making pages interactive on the client
  • CSS Files

image

Runtime: refers to the period of time when your application runs in response to a user's request

Rendering on Client/Server

Rendering: convert your reactjs code into HTML representation of your UI. Can be happened in

  • Client Side - Client Side Rendering
  • A head of time at build time - Static Side Generation ( Pre-Rendering )
  • Server Side - Every request at runtime - Server Side Rendering ( Pre-Rendering )

Pre-Rendering

image

Client-Side-Rendering

image

image

Server-Side-Rendering

image

Static-Side-Generation

image

Can you have multiple rendering methods into a single next.js application?

image

Next.js pre-renders every page by default

Content Delivery Networks ( CDN )

image

The Edge

Similar to CDNs, Edge servers are distributed to multiple locations around the world. But unlike CDNs, which store static content, some Edge servers can run code.

Pages & Links

NextJS Page Routes

image

image

Layouts

image

The main idea is creating a layout component which will wrap your page component. We can use the hierarchy file structure in nextjs to apply this pattern

// pages/_document.tsx
import { Html, Head, Main, NextScript } from "next/document";

export default function Document() {
  return (
    <Html lang="vi">
      <Head />
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  );
}

// pages/_app.tsx
import type { ReactElement, ReactNode } from "react";
import type { NextPage } from "next";
import type { AppProps } from "next/app";

import "../styles/global.scss";

export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
  getLayout?: (page: ReactElement) => ReactNode;
};

type AppPropsWithLayout = AppProps & {
  Component: NextPageWithLayout;
};

export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
  // Use the layout defined at the page level, if available
  const getLayout = Component.getLayout ?? ((page) => page);

  return getLayout(<Component {...pageProps} />);
}

// components/layout-default.tsx
import Meta from "./partials/meta-head";

const Layout = ({ children }) => {
  return (
    <>
      <Meta />
      <main>{children}</main>
    </>
  );
};

export default Layout;

Data Fetching

getServerSideProps

Return Props

export async function getServerSideProps(context) {
  return {
    props: {}, // will be passed to the page component as props
  }
}

image

404 Notfound

image

export const getServerSideProps: GetServerSideProps<{
  category: BlogCategoryModel;
}> = async (context) => {
  const { query } = context;
  const categorySlug = query.categorySlug;
  if (categorySlug === "posts") {
    return {
      notFound: true,
    };
  }
  const category: BlogCategoryModel = {
    title: `Category [${categorySlug}]`,
    posts: Array.from(new Array(6)).map((_, idx) => {
      return {
        title: `Post ${++idx}`,
        content: "",
        id: "1",
        featureImage: "",
        slug: "post-1",
      };
    }),
  };
  return {
    props: { category },
  };
};

Redirect

image

getStaticPaths and getStaticProps

image

import { GetStaticPaths, GetStaticProps } from "next";
import { useRouter } from "next/router";
import { PageModel } from "../business/models";
import Page from "../components/page";

export default (props: { page: PageModel }) => {
  const router = useRouter();
  const { page } = props;
  if (router.isFallback) {
    return <div>Loading...</div>;
  }
  //const { pageSlug } = router.query;
  return <Page page={page}></Page>;
};

export const getStaticPaths: GetStaticPaths = async () => {
  const paths = [{ params: { pageSlug: "lien-he" } }];
  return {
    paths,
    // don't build static page at build time, keep it for the 1st request
    // to reduce build time
    fallback: true,
  };
};

export const getStaticProps: GetStaticProps<{ page: PageModel }> = async ({
  params,
}) => {
  const pageSlug = (params["pageSlug"] as string) || "";
  const page: PageModel = {
    title: `Page with slug = ${pageSlug}`,
    slug: pageSlug,
    content: `Content of page with slug = ${pageSlug}`,
    featureImage: "",
    id: Math.random().toFixed(),
  };
  return {
    props: {
      page,
    },
  };
};

NextJS Environment

image

  • .env.[NODE_ENV] to load environment variables
  • Expose environment variables to the browser by prefixing with NEXT_PUBLIC_
@misostack
Copy link
Author

  • Stylesheets: sass, public assets: image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment