NextJS
Next is a React framework for building and deploying SSR applications.
WARNING
By default Next uses SSR. This means some packages which rely on React hooks will fail, with something that looks like this:
⨯ TypeError: (0 , react__WEBPACK_IMPORTED_MODULE_0__.createContext) is not a function
To fix these up, you can configure Next to run as a client-side SPA, or you can
Setup
Next provides their own create-next-app
CLI tool.
# Interactive setup of a new Next app
yarn create next-app
Routing
Routing in Next projects is done using one of two different built-in routers. Either the App Router (the new and recommended one) or the Pages Router.
You can use both routers simultaneously, however the App Router will take priority.
Making a new route
For the app router, you can create a new route by adding any level of nesting folders - which contain a file named page.js
(or page.jsx
or page.tsx
) - which has a single default export of a React server component.
To define a new route under <site>/cool
, it would look like:
app/
page.tsx
cool/
page.tsx
app/cool/page.tsx
export default function CoolPage() {
return <div>This is my really cool page :)</div>;
}
Built-ins and API
<Image />
component
Resolving local images is done for you in Next by using their Image component.
import Image from 'next/image';
export function Cat ({ catSource?: string }) {
return (
<Image
src={catSource ?? 'http://placekitten.com/200/300'}
/* The 'fill' forces the image to stretch to fill the container */
fill={true}
/* Without a fill key, you need to specify the width/height */
/* in pixels. */
width={200}
height={300}
/>
);
}
Usage
Default styles
NextJS comes with several default styles for their demo app, which can all be found under globals.css
as a sibling to the root page.
--> src/app (if using src/ folder)
--> page.tsx
--> globals.css - this file is required by the router
Client-side rendering
TLDR
If you just need to make something render on the client, use the React 'use client' directive.
Client-side rendering in Next is (seemingly) enabled on a page-by-page basis. Imagine this like Astros islands only less explicit.
Next will enable CSR for any page which contains a useEffect()
hook.
import React, { useEffect, useState } from "react";
export default function CSRPage() {
const [username, setUsername] = useState<string | undefined>();
useEffect(() => {
async function getUsername() {
const response = await fetch("some/api");
const { username } = await response.json();
setUsername(username);
}
getUsername();
}, [setUsername]);
return <div>Hi, {username}!</div>;
}
Client components
Client components are components explicitly marked to be rendered on the client-side.
// This part is the important bit!
"use client";
export default function SomeState() {
const [name, setName] = useState<string>("Joffrey");
// Imagine there's some state stuff in here 👻
return <>{name}</>;
}
Configuration
robots.txt
Adding a robots.txt to your Next app is just, adding it to the root of your app
directory.
package.json
next-env.d.ts
src/
--> app/
--> robots.txt
Import Aliases
// Don't do this!
import { Text } from "../../../../components/typography";
// Do this 😎
import { Text } from "@components/typography";
// Or, here's an example absolute import, from the root directory
// In this case 'components' resolves to 'src/components'.
import { Text } from "components/typography";
Configure these either in a TSConfig or in an equivalent jsconfig.json
.
Example configuration using only paths:
{
"compilerOptions": {
"paths": {
"@components/*": ["src/components/*"],
"@hooks/*": ["src/hooks/*"]
}
}
}
Example configuration using paths and baseUrl
:
{
"compilerOptions": {
"baseUrl": "src/",
"paths": {
"@components/*": ["components/*"],
"@hooks/*": ["hooks/*"]
}
}
}