Set up a Next.js project

The instructions below will guide you through the first step of the Next.js complete guide. These show you how to create a Next.js website with static components.

Next.js site with static components

Next.js website with static text and images.

You can also watch the video for step-by-step instructions detailed in the guide below.

Create a Next.js website with static components

If you have an existing Next.js project then you can skip this section and continue with the next section to make your Next.js project dynamic with Prepr content. Otherwise, let's get started.

Install a Next.js project

  1. Open a terminal, go to your development projects folder and execute the command below to create a new Next.js project called nextjs-complete-starter.

    npx create-next-app@latest nextjs-complete-starter

    Mark the options as shown in the image below to create the same project structure used in this guide.

    default options

  2. When the project is successfully created, go to the nextjs-complete-starter folder, the root directory of the project, and run the project with the following commands in the terminal:

    cd nextjs-complete-starter
    npm run dev
  3. You should now be able to view your app on your localhost, for example, http://localhost:3000/.

Update styling

Follow the steps below to add some simple styling to the project.

  1. In the terminal, stop the server you started in the above step (CTRL-C) and while in your project nextjs-complete-starter directory, install an additional package to make styling easier in the components you'll create below.

    npm install classnames
  2. Open the Next.js project with your preferred code editor.

Troubleshooting
If you don't have a src folder in your project, it means you selected No to the Would you like your code inside a src/ directory? question in the step above. You can either reinstall the Next.js project, or when you come across src in the rest of the instructions in this guide, use the root directory instead.

  1. Replace the styling in the globals.css file in the app folder to import the Tailwind CSS and to set up some additional colors and spacing:

    ./src/app/globals.css
    @import "tailwindcss";
     
    @theme {
        --font-size-mb-4xl: 2rem;
        --font-size-mb-5xl: 2.675rem;
        
        --spacing-8xl: 90rem;
        --container-8xl: 90rem;
        --container-prose: 50rem;
     
        --color-gray-50: #EEEEEE;
     
        --color-primary-50: #EFF6FF;
        --color-primary-100: #DBEAFE;
        --color-primary-600: #2563EB;
        --color-primary-700: #1D4ED8;
     
        --color-secondary-500: #4748B;
        --color-secondary-700: #334155;
    }

Add a simple navigation bar

  1. Create a components folder in the src directory and add the following three components to your Next.js project to display a navigation bar at the top of your website.

    ./src/components/button.tsx
    import {ComponentProps} from 'react'
    import classNames from 'classnames'
     
    export interface ButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
        children: React.ReactNode
        buttonStyle?: 'primary' | 'secondary'
        className?: string
    }
     
    export default function Button(props: ButtonProps)  {
        const { children, buttonStyle = 'primary', className, ...additionalProps } = props
        const classes = classNames(
            'flex rounded-full text-sm px-6 py-2.5 font-medium',
            buttonStyle === 'primary' && 'bg-primary-600 hover:bg-primary-700 text-white',
            buttonStyle === 'secondary' && 'bg-white hover:bg-gray-50 text-secondary-700',
            className 
        )
     
        return (
            <button className={classes} {...additionalProps}>
                {children}
            </button> 
        )
    }

Before you can view the navigation bar, you need to include it in the project layout.

Update the project layout

Follow the steps below to update the project layout to include the navigation bar and use Tailwind classes for styling.

  1. Go to the layout.tsx file in the src/app folder and remove the default code and replace it with the simplified layout below.

    ./src/app/layout.tsx
    import type {Metadata} from "next";
    import NavBar from "@/components/navbar";
    import './globals.css'
    import {Ubuntu} from "next/font/google";
     
    const ubuntu = Ubuntu({weight: ['400', '700'], subsets: ['latin']})
     
    export const metadata: Metadata = {
        title: "Prepr Next.js complete starter",
        description: "Showing the power of personalization and A/B testing",
    };
     
    export default function RootLayout({children}: Readonly<{children: React.ReactNode;}>) {
        return (
            <html lang="en">
                <body className={ubuntu.className}>
                    <NavBar/>
                    {children}
                </body>
            </html>
        );
    }
  2. In the src/app folder, replace the code in the page.tsx file with the following code to display your page.

    ./src/app/page.tsx
    export default function Page() {
        return (
            <div>
                <h1>My home page</h1>
            </div>
        );
    }
  3. Restart the localhost server with npm run dev in the terminal and go back to your browser. You should see the navigation bar and your heading text like in the image below.

    Update page with navigation bar

Once your Next.js project is created and working, you can create a static page with components.

Create static components

In this step, you'll create a static version of the page including two front-end components. One for a Hero section at the top of the page and another for Feature sections to highlight features for the company. Add these components to the front end as follows:

  1. Go to the src/app folder and create a new folder [[...slug]] and move the page.tsx file to this folder. This new folder creates a dynamic route (opens in a new tab) to all your pages.
  2. Refresh your page in the browser to check if your website still works.

Troubleshooting
Error: You cannot define a route with the same specificity as a optional catch-all route ...
Cause: You have two page.tsx files in your project.
Solution: Make sure the original page.tsx file is removed from the src/app folder when you moved it to the new [[...slug]] folder.

  1. Replace the simple code in the page.tsx with the code below to display the components with static data.

    ./src/app/[[...slug]]/page.tsx
    // Import the components to display them 
    import HeroSection from "@/components/sections/hero-section";
    import FeatureSection from "@/components/sections/feature-section";
     
    export default function Page() {
        return (
            <div>
                <HeroSection/>
                <FeatureSection/>
                <FeatureSection align='right'/>
                <FeatureSection/>
            </div>
        );
    }

You'll notice compilation errors in this page because the components don't exist yet. Continue the next steps to create these components and resolve these errors.

  1. In the src/components folder, create a new folder called sections. In this new folder, create new files called hero-section.tsx and feature-section.tsx and copy the code below to construct these components.

    ./src/components/sections/hero-section.tsx
    import Link from 'next/link'
    import Button from '@/components/button'
     
    export default function HeroSection() 
    {   
        return ( 
            <section className="bg-primary-50">
                <div className="mx-auto max-w-8xl p-spacing flex flex-col items-center md:flex-row gap-8 py-10 lg:py-20">
                    <div className="basis-6/12">
                        <h1 className="text-mb-5xl lg:text-7xl text-secondary-700 font-medium break-words text-balance">
                            Acme Lease
                        </h1>
                        <p className="text-mb-lg text-secondary-500 lg:text-lg mt-4 lg:mt-6 text-balance">
                            A car leasing company
                        </p>
                        <div className="flex gap-4 mt-8 xl:mt-10">
                        <div>
                            <Link href='#'><Button>Find your car</Button></Link>
                        </div>
                        </div>
                    </div>
                    <div className="basis-6/12 relative flex justify-end items-center">
                        <div className="z-10 flex items-center aspect-[20/17] w-9/12 overflow-hidden justify-center absolute top-1/2 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
                            <svg
                                    viewBox='0 0 402 260'
                                    className='w-full max-w-[400px]'
                                    fill='none'
                                    xmlns='http://www.w3.org/2000/svg'>
                                    <path
                                        d='M398.251 260H7.15201C4.49222 260 3.14794 256.795 5.01181 254.898L90.6954 167.668C94.5446 163.749 100.834 163.669 104.782 167.487L150.523 211.731C154.934 215.998 162.113 215.321 165.649 210.304L259.838 76.6611C263.834 70.9911 272.249 71.0127 276.216 76.703L400.712 255.284C402.099 257.273 400.676 260 398.251 260Z'
                                        fill='white'
                                    />
                                    <circle cx='50' cy='50' r='50' fill='white'/>
                                </svg>
                        </div>
                        <div
                            className="w-9/12 aspect-[20/17] bg-primary-100 rounded-3xl right-0 top-0 z-0">
                        </div>
                    </div>
                </div>
            </section>
        )
    }

When you go back to your page in the browser, you should now see something like the image below.

Next.js site with static components

Great work on getting your static web app working! Continue your journey to the next section to make your Next.js project dynamic with Prepr content.

Was this article helpful?

We’d love to learn from your feedback