## NEXT.js's Basic Features - Styling - `styled-jsx`: define styles within `jsx` files. - Built in support for importing `css` and `scss` files directly within JavaScript files. - Builtin sass support, `npm i -D sass` before using sass. - Regular (non-global) `css` files must be named `*.module.css`. They are - Global Styles: define a `css` file and import it from within `pages/_app.js`. - Toggle classnames with `classnames` library - Out of the box, `Next.js` compiles CSS using [PostCSS](https://postcss.org/), create a top level file `postcss.config.js` to customize. For example, when using [Tailwind](https://tailwindcss.com/). - `next/link` can link to another page (within the website) without refreshing the web page. - `next/image` resize and optimize images. - `next/head` define head for a page - `next/script` is an extension of regular `script` tag, with extra functions: `onLoad` callback, strategy (when to load). It can be defined within `<Head>` tag. ## Pre-rendering and Data Fetching [Data Fetching](https://nextjs.org/docs/basic-features/data-fetching/overview) - 2 forms of pre-rendering: - Static Generation (with or without data) - Pre-rendered and saved, basically serving static files. - Use Static Generation whenever possible, pages can be served by CDN, much faster than server-side rendering. - Without data: client-side rendering - Server-side Rendering - Render page on server and send back to client (requires a server running) - When content is dynamic (load from database), you may have to use server-side rendering or client-side rendering to keep data displayed always up to date. It's still possible to use Static Generation with a remote CMS. Pre-rendering is on per-page basis, i.e. choose different modes for different pages ### Static Generation with Data using `getStaticProps` (SSG) Export an `async` function called `getStaticProps` and return the data fetched as props to UI component. #### Sample Code ```jsx export default function Home(props) { ... } export async function getStaticProps() { // Get external data from the file system, API, DB, etc. const data = ... // The value of the `props` key will be // passed to the `Home` component return { props: ... } } ``` - `getStaticProps` never runs on client side, so it's ok to write server side code such as database connection. - `getStaticProps` can only be exported from a page. ### Fetching Data at Request Time (SSR) Use Server-side rendering instead. Export an `async` function called `getServerSideProps`, which will be called on server for every request. #### Sample Code ```jsx function Page({ data }) { // Render data... } // This gets called on every request export async function getServerSideProps() { // Fetch data from external API const res = await fetch(`https://.../data`); const data = await res.json(); // Pass data to the page via props return { props: { data } }; } export default Page; ``` ### Client-side Rendering If you **do not** need to pre-render the data, try client-side rendering. Client-side rendering is usually used in private, user-specific pages where SEO is not relevant. - Statically generate (pre-render) parts of the page that don't rely on external data. - Fetch external data on client side within the browser using JavaScript, then render the page. #### SWR Use SWR in client-side rendering. It handles caching, revalidation, focus tracking, refetching on interval, and more. ```jsx import useSWR from "swr"; function Profile() { const { data, error } = useSWR("/api/user", fetch); if (error) return <div>failed to load</div>; if (!data) return <div>loading...</div>; return <div>hello {data.name}!</div>; } ``` ## Dynamic Routes ### Statically Generate Pages with Dynamic Routes Support dynamic routes like `/posts/<id>`, where `id` is a variable, linking to different post pages. Route `posts/<id>` can be achieved by creating file `pages/pots/[id].js`. Add async functions `getStaticPaths` and `getStaticProps`. ```jsx export default function Post() { return <Layout>...</Layout>; } export async function getStaticPaths() { // Return a list of possible value for id } export async function getStaticProps({ params }) { // Fetch necessary data for the blog post using params.id } ``` Notice that the `getStaticProps` function now has a props called `params`. The return type of `getStaticPaths` should be ```ts type Params = { params: { id: string; }; }[]; type RetType = { paths: Params; fallback: Boolean; }; ``` The attribute in `Params` (`id`) should correspond to the filename `[id].js`. `getStaticPaths` can also fetch data from external API. ## API Routes [API Routes] lets you create API endpoints inside a Next.js app. Create a function under `pages/api` directory. ```jsx // req = HTTP incoming message, res = HTTP server response export default function handler(req, res) { res.status(200).json({ text: "hello" }); } ``` ## Reference - https://nextjs.org/learn/basics/create-nextjs-app - https://nextjs.org/docs/getting-started