A Quick and Dirty Next.js Project Setup

author avatar
PC

Introduction

If you've found this, you likely have an idea of what Next.js is and what it can do. If not, Next.js is a React framework that has some cool features like server-side rendering. It's a great tool for building full stack web applications.

Contents

Getting Started

First things first, you'll need to setup a new Next.js project. You can do this by running the following command in a terminal:

npx create-next-app@latest my-app-name
npx create-next-app@latest my-app-name

Navigate into the directory where you want you project to live and run the command above. Replace my-app-name with the name of your project.

Now you can open the project in the code editor of your choice.

Planning the rest of the project

Before I start coding, I like to plan the project a bit to get a sense of what sort appication I'll be building. This way I have an idea of the tools I need and how I can integrate them. For example, most production web products will need some sort of database. When I need a database I tend to reach for PostgreSQL because I'm familiar with it and find it easy to work with on my local machine. There are other options like MongoDB, MySQL, and SQLite. You can use whatever you're comfortable with.

Setting up a database

For local development all I do is create a new local database using the following command in the terminal:

createdb my-database-name
createdb my-database-name

To connect to the database so I can run queries, I pull in an ORM. My favorite is Prisma but others Drizzle seems to be gaining popularity. So far I haven't personally run into an issue with Prisma that would be solved by another ORM so I'll continue to use Prisma.

To install Prisma, run the following command in the terminal:

npm install prisma --save-dev
npm install prisma --save-dev

This installs the Prisma CLI as a dev dependency in your project.

Now we can easily initialize a Prisma in our project by running the following command in the terminal:

npx prisma init --datasource-provider postgresql
npx prisma init --datasource-provider postgresql

This command creates a directory called prisma in your project with a schema.prisma file. This file is where you define your database schema. If you open the schema.prisma file you should see something like this:

generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}
generator client {
provider = "prisma-client-js"
}

datasource db {
provider = "postgresql"
url = env("DATABASE_URL")
}

What matters here is the datasource block. This is where you define the connection to your database. You can see that the provider is set to postgresql and the URL is set to env("DATABASE_URL"). This is where you would put the URL to your database. For local development, you can replace env("DATABASE_URL") with the URL to your local database. For example, if you're using PostgreSQL, In your .env file you can add the following:

DATABASE_URL="postgresql://username:password@localhost:5432/my-database-name"
DATABASE_URL="postgresql://username:password@localhost:5432/my-database-name"

This is the URL to your local database. Replace username, password, and my-database-name with your own values. In local development username and password will be the credentials you use to login to your computer unless you specified a different database user when you created the database.

Finally, to finish our Prisma setup we'll need to grab the Prisma client, which allows us to interact with our database from you code.

npx prisma migrate dev --name init
npx prisma migrate dev --name init

This command will look at your connection string, connect to the database and from your schema will create the tables and columns defined in your schema. The Prisma client will also be installed into your project so so you can start querying your database.

Authentication

We've now got persistent data setup but no way to control access to it nor restrict access to certain parts of our application. This is a pretty import piece of modern web applications so lets get setup with authentication.

I like to use NextAuth for authenticating users because it's easy to setup and has many providers built in. I also don't like to change tooling unless I personally run accross an issue not solved by what I'm using. So far NextAuth has been great for me. To install NextAuth, run the following command in the terminal:

npm install next-auth@beta
npm install next-auth@beta

Don't be alarmed by the @beta tag. NextAuth is, at the time of writing in the process of upgrading to v5 and I recommend, if you're starting a new project to use it. It's stable and has some nice new features, maybe just don't use it for mission critical production applications until it's out of beta.

In the app folder of the project create a directory named api inside that directory create another directory named auth. Inside the auth directory create yet another directory [...nextauth]. Be sure to include the square brackets in the directory name. This is where we'll put our NextAuth API route. in the [...nextauth] directory create a file named route.ts and add the following code:

export { GET, POST } from "./auth";
export { GET, POST } from "./auth";

In the same directory create the auth.ts file imported by the route.ts file and add the following code:

import NextAuth from "next-auth";

export const {
handlers: { GET, POST },
auth,
} = NextAuth({
providers: [],
});
import NextAuth from "next-auth";

export const {
handlers: { GET, POST },
auth,
} = NextAuth({
providers: [],
});

Add any provider you want to support in your application such as Google or Github. You can find a list of providers here.

Now you can add authentication by importing the auth function into components, pages, middleware, api routes, etc. Calling the function will return the user session: Here is an example in a page file:

import { auth } from "path/to/auth";

export default async function Page() {
const session = await auth();
return <p>Welcome {session?.user.name}!</p>;
}
import { auth } from "path/to/auth";

export default async function Page() {
const session = await auth();
return <p>Welcome {session?.user.name}!</p>;
}

There you have it, now you can dynamically display data based on the user session, or restrict access to api routes if the user is not authenticated and all the other useful things that come with auth.

Wrapping Up

This is my quick and dirty Next.js project setup. I follow this general path for most new projects I undertake if I am building a full stack web application. I find the tools listed provide a good balance of functionality and ease of use to get up and running quickly. Of course, this is not a comprehensive guide, but rather a starting point to build the foundations of most modern web applications. Depending on what your building the tools you use may differ and you'll certainly need to add more features to build a production ready application. My hope is that this serves as a good starting point for you to build your own projects.

Happy coding! 🚀

Resources