# NextJS CheatSheet npx create-next-app seo --use-yarn --example "https://github.com/vercel/next-learn/tree/master/basics/learn-starter" ## Overview Architecture ![image](https://user-images.githubusercontent.com/31009750/189313577-11914637-69ac-41b3-b484-ad94af5e62c9.png) > Main Concept ### Development vs Production **Development stage:** TypeScript and ESLint integration, Fast Refresh, ... **Production stage:** Compiled, Bundled, Minified and Code Split ![image](https://user-images.githubusercontent.com/31009750/189321689-850dec65-79e9-471c-955b-e4e6a678dbe2.png) > Compiled : JSX -> should be transformed to JS version that browser can understand ![image](https://user-images.githubusercontent.com/31009750/189316973-d408a03b-9ad8-4608-acc3-bfa81b0837f2.png) NestJS use [SWC](https://swc.rs/) to replace Babel as a compiled tool. > Minifying: Removed unnessary code formatting and comments without changing the code's functionality ![image](https://user-images.githubusercontent.com/31009750/189317028-902e7d38-5eaa-4dff-ba49-62fcbfe16b5a.png) > 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](https://user-images.githubusercontent.com/31009750/189318349-8c2ade40-4cf1-4ade-b6c7-62d1f41afee1.png) > 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](https://user-images.githubusercontent.com/31009750/189318282-07a77775-9351-457f-b897-dabc328e9943.png) ### 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](https://user-images.githubusercontent.com/31009750/189322997-c68d4fe7-da1d-46fa-a438-c21995bb11b2.png) > 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](https://user-images.githubusercontent.com/31009750/189324555-02b5f607-0551-4084-9787-85d151dbc660.png) **Client-Side-Rendering** ![image](https://user-images.githubusercontent.com/31009750/189324919-4598e6f9-85f4-4252-b4c5-cca03c0116f4.png) ![image](https://user-images.githubusercontent.com/31009750/189325940-14dc0a09-b787-4294-b8a7-7bf8aec15927.png) **Server-Side-Rendering** ![image](https://user-images.githubusercontent.com/31009750/189326613-2c9ade67-a395-4142-8847-2770ede4ab2d.png) **Static-Side-Generation** ![image](https://user-images.githubusercontent.com/31009750/189327114-c93a0b62-0a0d-4585-9fe8-2629a53289a2.png) **Can you have multiple rendering methods into a single next.js application?** ![image](https://user-images.githubusercontent.com/31009750/189327427-84665ea2-163f-4700-b097-1dbef1bedea0.png) > Next.js **pre-renders** every page by **default** ### Content Delivery Networks ( CDN ) ![image](https://user-images.githubusercontent.com/31009750/189328170-4990e603-17cf-463f-bd98-8c21f8b70fe9.png) ### 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](https://user-images.githubusercontent.com/31009750/189331611-f7dc0b51-de1f-4d66-8e89-3dee2c7ced3b.png) ![image](https://user-images.githubusercontent.com/31009750/189333653-0cfd5017-d1c8-44b8-880b-c2730598580b.png) ### Layouts ![image](https://user-images.githubusercontent.com/31009750/190055658-077b00a1-1fd2-4423-bfc6-5fd6a3977e81.png) 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 ```tsx // pages/_document.tsx import { Html, Head, Main, NextScript } from "next/document"; export default function Document() { return (
); } // 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

= NextPage & { 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(); } // components/layout-default.tsx import Meta from "./partials/meta-head"; const Layout = ({ children }) => { return ( <>

{children}
); }; export default Layout; ``` ## Data Fetching ### getServerSideProps #### Return Props ```ts export async function getServerSideProps(context) { return { props: {}, // will be passed to the page component as props } } ``` ![image](https://user-images.githubusercontent.com/31009750/190312415-69d88401-1238-4e86-9911-f91ae11d421a.png) #### 404 Notfound ![image](https://user-images.githubusercontent.com/31009750/190581688-74b9b6e0-d493-497b-a52c-7777cb436b47.png) ```ts 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](https://user-images.githubusercontent.com/31009750/190581836-de313208-7dd6-41b2-bc75-4ee59b7bdfea.png) ### getStaticPaths and getStaticProps ![image](https://user-images.githubusercontent.com/31009750/190840369-d6844d5a-cf36-4dad-93cf-969ea6b2eb8f.png) ```ts 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
Loading...
; } //const { pageSlug } = router.query; return ; }; 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](https://user-images.githubusercontent.com/31009750/190902902-a760c9bd-dffb-4d13-99ec-bb65d2291bda.png) - .env.[NODE_ENV] to load environment variables - Expose environment variables to the browser by prefixing with NEXT_PUBLIC_