DEV Community

Cover image for Setup your NextJS app
Dušan Perković
Dušan Perković

Posted on

Setup your NextJS app

If you're looking to setup easy authentication for your users in NextJS, you're in the right place!

In this guide, I will show you all the steps necessary to setup your NextJS app, add google authentication to it (the Sign In With Google button), and deploy the application to production (using Vercel).

This is the first part of the guide, which will focus on just setting up your NextJS environment.

Generating the boilerplate

To setup our app, we're gonna use the tried and true method from the official documentation. NextJS has a great CLI tool, which you don't even need to install separately.
If you already have node installed, simply run npx create-next-app@latest in your projects directory, and answer the following questions as you please. Since I'm a big fan of Tailwind and TypeScript, this is the setup I used:

Next project setup

Creating the pages

Let's personalize our app a bit. We can start by adding our sign in, and sign out buttons.

app/components/SignInButton.tsx

"use client"

import { useRouter } from "next/navigation"

export const SignInButton = () => {
  const { push } = useRouter();

  return (
  <button 
    onClick={() => push("/")}
    type="button" className="text-white w-full bg-[#4285F4] hover:bg-[#4285F4]/90 focus:ring-4 focus:outline-none focus:ring-[#4285F4]/50 font-medium rounded-lg text-sm px-5 py-2.5 text-center inline-flex items-center justify-center dark:focus:ring-[#4285F4]/55">
    <GoogleIcon />
    Sign in with Google
  </button>
  )
}

const GoogleIcon = () => (
  <svg
    xmlns="http://www.w3.org/2000/svg"
    aria-hidden="true"
    className="mr-2 -ml-1 w-4 h-4"
    data-icon="google"
    data-prefix="fab"
    viewBox="0 0 488 512"
  >
    <path
      fill="currentColor"
      d="M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"
    />
  </svg>
)
Enter fullscreen mode Exit fullscreen mode

app/components/SignOutButton.tsx

"use client"

import { useRouter } from "next/navigation"

export const SignOutButton = () => {
  const { push } = useRouter();
  return (
    <button className="text-black hover:text-sky-600"
      onClick={() => push("/signin")}
    >Sign out</button>
  )
}
Enter fullscreen mode Exit fullscreen mode

For now, the only thing that should happen when clicking on these buttons is a redirect to the home page (/), or to the sign in page (/signin).

A note on "use client": This is a new syntax specific to using NextJS with the App router. It marks the component as a client component, which means it needs to load JavaScript on the client side.
Client components are different from server components, which render only on the server. If you would like a deeper explanation of server vs client components, you can check out the official documentation on server components and client components.

Next, let's create our Sign in page, so we can use our signin button!

app/signin/page.tsx

import { redirect } from "next/navigation";
import { Metadata } from "next";
import { SignInButton } from "../components/SignInButton";

export const metadata: Metadata = {
  title: 'Signin',
  description: 'Please sign in ',
}

export default async function SignInPage() {

  return (
    <>
      <div className="flex min-h-full flex-1 flex-col justify-center px-6 py-12 lg:px-8">
        <div className="sm:mx-auto sm:w-full sm:max-w-sm">
          <h2 className="mt-10 text-center text-2xl font-bold leading-9 tracking-tight text-gray-900">
            Sign in to your account
          </h2>
        </div>

        <div className="mt-10 sm:mx-auto sm:w-full sm:max-w-sm">
          <SignInButton />
        </div>
      </div>
    </>
  )
}
Enter fullscreen mode Exit fullscreen mode

Regarding the global styling, we can remove almost everything from the global.css file, and leave only the following:

app/global.css

@tailwind base;
@tailwind components;
@tailwind utilities;
Enter fullscreen mode Exit fullscreen mode

This will just apply the Tailwind CSS reset, and make it possible to use Tailwind classes inside our components.

For the home page itself, let's just make it as simple as possible and just leave some text indicating we're on the homepage, and also add our SignOutButton so we can navigate back to the sign in page:

app/page.tsx

import { SignOutButton } from './components/SignOutButton';

export default async function Home() {

  return (
    <>
      <header className="border-b border-gray-200 bg-white">
        <div className="mx-auto max-w-7xl px-4">
          <div className="flex gap-10 items-center w-full justify-between lg:justify-end my-2 px-4">
            <SignOutButton />
          </div>
        </div>
      </header>
      <main className="flex min-h-screen flex-col items-center justify-between p-24">
        <h1>Hello from the homepage!</h1>
      </main>
    </>
  )
}

Enter fullscreen mode Exit fullscreen mode

Running our app now using npm run dev, and visiting http://localhost:3000 in the browser should show the following:

Home page

And clicking on Sign Out, should take you to the /signin page, which should look like this:

Sign In page

Here's a link to the acompanying github repo, which contains all the code from this blogpost.
I have also deployed this code snippet on Vercel, available here.

But what good are all these sign in and sign out buttons without some actual authentication logic behind them?

We will expand on that topic in the following chapter!

Top comments (0)