Building Modern Web Applications with Next.js and TypeScript

Tina Huynh - Nov 5 - - Dev Community

Next.js has become one of the most popular React frameworks for building high-performance web applications with server-side rendering, static site generation, and powerful routing out of the box. When combined with TypeScript, Next.js offers the benefits of strong typing and type safety, making applications easier to debug, maintain, and scale.


What is Next.js?

Next.js is a React-based framework that simplifies creating server-rendered and statically generated applications. Its main benefits include:

  • Server-Side Rendering (SSR): Fetch and render data on the server, improving SEO and page load times.
  • Static Site Generation (SSG): Generate static HTML files at build time, ideal for high-performance sites.
  • API Routes: Handle backend logic within the same framework, allowing a full-stack setup.
  • Automatic Code Splitting: Only load the JavaScript needed for the current page, improving performance.

Next.js provides a complete toolkit for building modern web applications, from frontend to backend, without setting up complex configurations.


Setting Up a Next.js Project with TypeScript

You can create a new Next.js project with TypeScript by following these steps:

Step 1: Create a New Next.js Project

Run the following command in your terminal:

npx create-next-app@latest my-nextjs-app
Enter fullscreen mode Exit fullscreen mode

During setup, you’ll be prompted to select TypeScript. If not, you can add TypeScript later by installing TypeScript and the necessary type declarations.

Step 2: Add TypeScript to an Existing Project

If you already have a Next.js project and want to add TypeScript, install the following packages:

npm install --save-dev typescript @types/react @types/node
Enter fullscreen mode Exit fullscreen mode

Once installed, add a tsconfig.json file to the root of your project. Next.js will automatically configure the tsconfig.json with the recommended settings when you restart the development server.

Step 3: Start the Development Server

To see the project in action, run:

npm run dev
Enter fullscreen mode Exit fullscreen mode

The app will be accessible at http://localhost:3000.


Exploring the Next.js Project Directory

When you create a Next.js project, it generates a default directory structure with the following folders:

  • pages/: Contains all the route components. Each file corresponds to a route, with index.js being the home page.
  • public/: Holds static files like images, icons, and other assets that don’t need to be processed by webpack.
  • styles/: Stores CSS files for styling. By default, this folder includes globals.css (for global styles) and Home.module.css (module-based styling for specific components).
  • components/: A common practice is to create a components folder to hold reusable components, though this is not part of the default Next.js structure.

Routing in Next.js

Next.js provides a built-in file-based routing system, simplifying route creation. Each file in the pages/ directory automatically becomes a route.

Basic Routing

  • pages/index.tsx: Becomes the root route (/).
  • pages/about.tsx: Becomes /about.
  • pages/blog/index.tsx: Becomes /blog.

Nested Routes

Nested folders in the pages directory correspond to nested routes. For example:

  • pages/blog/index.tsx: /blog
  • pages/blog/[id].tsx: /blog/:id

Dynamic Routes

To create dynamic routes, use square brackets in the filename. For example, if you want to create a dynamic route for blog posts, name the file [id].tsx:

  • pages/blog/[id].tsx: /blog/[id]

The dynamic route can then be accessed with the useRouter hook from next/router to retrieve route parameters.

import { useRouter } from 'next/router';

const BlogPost = () => {
  const router = useRouter();
  const { id } = router.query;

  return <div>Blog post ID: {id}</div>;
};

export default BlogPost;
Enter fullscreen mode Exit fullscreen mode

This approach allows you to create parameterized routes without additional libraries or setup.


TypeScript in Next.js: Type Safety for Components and Pages

Using TypeScript in Next.js enhances code reliability by catching type errors at compile time, making code easier to read and maintain. Let’s look at how to type components and pages.

Typing Functional Components

Define props interfaces for components to enforce strong typing. For instance, a button component might look like this:

import React from 'react';

interface ButtonProps {
  text: string;
  onClick: () => void;
}

const Button: React.FC<ButtonProps> = ({ text, onClick }) => (
  <button onClick={onClick}>{text}</button>
);

export default Button;
Enter fullscreen mode Exit fullscreen mode

Typing Next.js Pages

Next.js pages can also be strongly typed using TypeScript. If a page fetches data using getStaticProps or getServerSideProps, type these functions for additional safety.

import { GetStaticProps, NextPage } from 'next';

interface HomePageProps {
  message: string;
}

const HomePage: NextPage<HomePageProps> = ({ message }) => {
  return <div>{message}</div>;
};

export const getStaticProps: GetStaticProps = async () => {
  return {
    props: { message: 'Hello from Next.js with TypeScript!' },
  };
};

export default HomePage;
Enter fullscreen mode Exit fullscreen mode

In this example, HomePage is typed as a NextPage with HomePageProps, and getStaticProps is typed as GetStaticProps, ensuring strong typing throughout the page.


API Routes in Next.js

Next.js allows you to create backend API endpoints within the same project using the pages/api directory. Each file in this directory maps to an API route, providing full-stack functionality.

Example: Creating a Simple API Endpoint

To create an endpoint, add a file like hello.ts in pages/api:

import { NextApiRequest, NextApiResponse } from 'next';

export default (req: NextApiRequest, res: NextApiResponse) => {
  res.status(200).json({ message: 'Hello from Next.js API!' });
};
Enter fullscreen mode Exit fullscreen mode

This endpoint can be accessed at /api/hello. You can use TypeScript’s NextApiRequest and NextApiResponse types to enforce types on requests and responses.

Using API Routes with TypeScript

TypeScript allows you to type query parameters, request bodies, and responses to ensure data consistency across API routes. For example:

export default (req: NextApiRequest, res: NextApiResponse<{ name: string }>) => {
  if (req.method === 'POST') {
    const { name } = req.body;
    res.status(200).json({ name });
  } else {
    res.status(405).json({ name: 'Method Not Allowed' });
  }
};
Enter fullscreen mode Exit fullscreen mode

This example only allows POST requests and types the response as an object with a name property.


Configuring tsconfig.json in Next.js

Next.js automatically creates a tsconfig.json with recommended settings. However, you can customize it based on your project requirements. Here’s an example configuration:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "forceConsistentCasingInFileNames": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "node",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve"
  },
  "exclude": ["node_modules"],
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}
Enter fullscreen mode Exit fullscreen mode

These options include strict mode for stricter type checking and noEmit to prevent TypeScript from generating .js files.


Benefits of Using Next.js with TypeScript

By combining Next.js with TypeScript, you unlock several key advantages:

  • Improved Developer Experience: Type safety helps catch errors early and provides a better coding experience with autocompletion and type hints.
  • Enhanced Code Maintainability: Strongly typed components, pages, and API routes make large projects more manageable.
  • Scalability: TypeScript’s structure makes scaling Next.js projects easier as teams grow or codebases become more complex.
  • Code Consistency: TypeScript enforces consistent coding practices across the project.

Conclusion

Next.js combined with TypeScript provides a robust, flexible framework for building scalable web applications with a smooth developer experience. By understanding the Next.js project structure, routing, and how to use TypeScript effectively, you can create applications that are type-safe,

organized, and optimized for performance.

With its built-in API routes, file-based routing, and strong TypeScript integration, Next.js makes building full-stack React applications easier than ever. Give it a try in your next project and see the difference for yourself!

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
Terabox Video Player