A Beginner’s Guide to Next.js: Mastering the Core Concepts

Awais Rasheed
3 min readSep 28, 2024

--

When starting with Next.js, you might be tempted to rely on YouTube tutorials or blog posts for learning. It’s easy to fall into the trap of constantly jumping from one tutorial to another, where creators often contradict themselves in search of views. I’ve been there, and after spending time sifting through various guides, I found the best way to learn Next.js is to stick to the official documentation. The docs focus on what matters most — Next.js’s core concepts. In this guide, we’ll break down those essential building blocks to help you get started.

The Core Concepts You Must Master

The goal here is simple: focus on the fundamentals first before diving into third-party tools or complex patterns. Master these and you’ll be well-equipped to build real-world applications without over-complicating your process.

1. Routing: Structuring Pages and Dynamic Routes

Next.js makes routing dead simple. The routing is file-based, meaning every file you create under the pages/ directory automatically becomes a route.

Static Routes

If you create a pages/about.tsx, Next.js will generate a /about route automatically. No need to configure anything.

Dynamic Routes

For dynamic routes, you can use the bracket syntax, such as [id].tsx. This allows you to capture route parameters. Here’s an example of how to structure a dynamic route:

export async function getServerSideProps({ params }: { params: { id: number } }) {
// Fetch data based on the ID
const data = await fetchDataById(params.id);
return { props: { data } };
}

This dynamic route lets you build pages like /products/1 or /user/123, where 1 and 123 are IDs passed as params.

2. The Image Component: Optimizing Images

Next.js includes a built-in <Image /> component, which automatically optimizes images. This is crucial for performance, as it reduces loading times and improves SEO.

Key points:

  • Always set width and height for images.
  • For small images, set lower dimensions to save memory and speed up loading.
import Image from 'next/image';

<Image
src="/small-image.jpg"
alt="Small example"
width={100}
height={100}
/>

If the image will always be small across devices, keeping its dimensions tight ensures a lighter load, improving the user experience.

3. Server-Side Data Fetching

Next.js simplifies server-side data fetching through its getServerSideProps and getStaticProps functions.

Fetching Data on the Server

I usually centralize my server data fetching by creating a functions.ts file that contains all server-side fetch logic. This keeps your code clean and makes the actual page component simpler.

Example:

// functions.ts
export async function getPeople() {
const response = await fetch('/api/people');
return response.json();
}

// page.tsx
export async function getServerSideProps() {
const people = await getPeople();
return { props: { people } };
}

export default function PeoplePage({ people }) {
return <div>{people.map(person => <p key={person.id}>{person.name}</p>)}</div>;
}

4. Suspense for Data Loading

Next.js now supports React’s Suspense feature for better loading experiences. When you’re fetching data on the server, wrap your component inside a Suspense block to show a loading skeleton while the data loads.

import { Suspense } from 'react';
import ItemsSkeleton from './ItemsPage';

export default function ItemsPagge() {
return (
<Suspense fallback={<ItemsSkeleton />}>
<Items />
</Suspense>
);
}

This enhances user experience by preventing the dreaded “flash of no content.”

5. Client-Side Data Fetching

For client-side fetching, React Query is an excellent library, but you should first master the basics of React’s useEffect and fetch.

After you’ve built a basic understanding, you can centralize all client-side data fetching into a clientFetch.ts file and utilize hooks to retrieve the data.

Example with react-query:

import { useGetPeople } from './clientFetch';

export default function MessagingComponent() {
const { data: people } = useGetPeople();
return <div>{people.map(person => <p key={person.id}>{person.name}</p>)}</div>;
}

Keeping Things Simple: Focus on Core Concepts

Resist the temptation to solve problems you don’t have yet. Start small, build a basic product, and iterate. Once you have something functional, you can start exploring tools to improve your developer experience, such as React Query for state management.

Some good UI libraries to help in the design & UI components!

Shadcn,
AcertinityUI
MagicUI
HyperUI
NextUI
animata.design
motion-primitives
daisyui
RadixUI
HeadlessUI
motion-primitives
daisyui
RadixUI

Learning Next.js doesn’t have to be overwhelming. Avoid distractions, and focus on the core principles. The more time you spend experimenting with these basics, the easier it becomes to pick up more advanced tools and concepts.

--

--