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.

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.

We're currently evaluating the latest versions of Next.js. In the meantime, we've chosen to base this guide on Next.js version 14. Don't hesitate to contact us (opens in a new tab) about using newer Next.js releases with this guide.

Install a Next.js project

  1. Open a terminal and execute the command below to create a new Next.js project called nextjs-advanced-starter.

    npx create-next-app@14 nextjs-advanced-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-advanced-starter folder, the root directory of the project, and run the project with the following commands in the terminal:

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

Add a simple navigation bar

Follow the steps below to add a simple navigation bar to your project.

  1. While in your project nextjs-advanced-starter directory, install an additional package to make styling easier in the components you'll create below.
npm install classnames
  1. 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. 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 ComponentProps<'button'> {
    children: React.ReactNode
    buttonType?: 'primary' | 'secondary'
    className?: string
}
 
export default function Button({children, buttonType = 'primary', className, ...props}: ButtonProps) {
    const classes = classNames(
        'py-2.5 px-6 rounded-full text-sm font-bold',
        buttonType === 'primary' && 'bg-blue-600 text-white hover:bg-blue-700',
        buttonType === 'secondary' &&
        'bg-white text-neutral-900 hover:bg-gray-100',
        className
    )
 
    return (
        <button className={classes} {...props}>
            {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 advanced 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>
    );
}
  1. Replace the styling in the globals.css file in the app folder to only include the Tailwind CSS directives with the following code:
./src/app/globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
  1. 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>
  );
}
  1. 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 Header section and another for Image and text sections. 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 HeaderSection from "@/components/HeaderSection";
import ImageAndTextSection from "@/components/ImageAndTextSection";
 
export default function Page() {
    return (
        <div>
            <HeaderSection/>
            <ImageAndTextSection/>
            <ImageAndTextSection align='right'/>
            <ImageAndTextSection/>
        </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 new files called HeaderSection.tsx and ImageAndTextSection.tsx and copy the code below to construct these components.
./src/components/HeaderSection.tsx
import Link from "next/link";
 
export default function HeaderSection() {
    return (
        <div className='px-4 md:px-10 lg:px-20'>
            <div className='mx-auto max-w-7xl w-full'
            >
                <div className='flex flex-wrap gap-y-8 py-16 md:flex-nowrap flex-shrink-0'>
                    <div
                        className='flex items-start justify-start flex-grow-0 flex-col space-y-16 md:basis-8/12 lg:basis-7/12'>
                        <h1 className='text-neutral-900 text-5xl font-medium lg:text-6xl'>
                            Acme lease
                        </h1>
                        {/* Searchbar */}
                        <div className='flex items-stretch justify-stretch w-full sm:max-w-xl rounded-full'>
                            <div
                                className='flex w-full justify-between rounded-l-full border-2 border-blue-600 bg-white px-4 py-2 lg:px-8 lg:py-4'>
                                <div
                                    className='flex w-full basis-5/12 items-center justify-between gap-3 md:gap-6 text-lg md:text-xl text-black hover:cursor-pointer lg:text-2xl'>
                                    <span>Brand</span>
                                    <TriangleDownIcon/>
                                </div>
                                <div className='mx-4 h-10 border-l-[1px] border-l-black lg:mx-5'></div>
                                <div
                                    className='flex basis-5/12 items-center justify-between gap-3 md:gap-6 text-lg md:text-xl text-black hover:cursor-pointer lg:text-2xl'>
                                    <span>Model</span>
                                    <TriangleDownIcon/>
                                </div>
                            </div>
                            <Link
                                href='/catalog'
                                className='flex items-center text-nowrap rounded-r-full bg-blue-600 px-4 text-base md:text-lg font-bold text-white hover:cursor-pointer hover:bg-blue-700 lg:px-8 lg:text-2xl'>
                                FIND A CAR
                            </Link>
                        </div>
                    </div>
                    <div className='flex w-full justify-end md:basis-6/12 lg:h-[23.75rem] lg:basis-7/12'>
                        <div
                            className='order-first flex max-h-[542px] w-full flex-grow basis-6/12 items-center justify-center bg-blue-50 p-16 md:order-none md:p-12 lg:p-16'>
                            <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='#DBEAFE'
                                />
                                <circle cx='50' cy='50' r='50' fill='#DBEAFE'/>
                            </svg>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    )
}
 
function TriangleDownIcon() {
    return (
        <svg
            xmlns='http://www.w3.org/2000/svg'
            width='18'
            height='18'
            viewBox='0 0 18 18'
            fill='none'>
            <path
                d='M9.86603 16.5C9.48112 17.1667 8.51888 17.1667 8.13398 16.5L2.0718 6C1.6869 5.33333 2.16802 4.5 2.93782 4.5L15.0622 4.5C15.832 4.5 16.3131 5.33333 15.9282 6L9.86603 16.5Z'
                fill='currentColor'
            />
        </svg>
    )
}

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

Static site

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