App Shell and Styling
Introduction: The App Shell in Next.js
Welcome to your first lesson in a course path titled Introduction to Frontend Development with Next.js.
This course is part of a bigger learning path where we focus on building real applications with Next.js.
In the previous course path, Introduction to Backend Development with Next.js, we built a backend API with routes, services, and in-memory data. That course was all about how to structure backend logic.
Here, we’ll switch to the frontend side. In this course, you’ll build a focused read-only UI that connects to that backend, including a reusable app shell, dashboard statistics, and a task list.
👉 Don’t worry if you didn’t take the backend course. While it’s recommended for extra context, this course assumes no prior backend knowledge. We’ll provide you with a fully working backend so you can focus entirely on building the frontend.
Project Packages and Setup
In CodeSignal, all the necessary packages are already pre-installed, so you don’t have to worry about setup. But if you wanted to work locally on your own machine, you would typically install:
- Next.js – the React framework we’re using for both frontend and backend.
- React and React DOM – the core React libraries.
- TypeScript – adds type safety to your project.
- Tailwind CSS – a utility-first CSS framework for styling.
The installation command would look something like this:
This single command creates a new Next.js project with both TypeScript and Tailwind configured for you. After that, you’d run npm run dev to start the local development server.
In CodeSignal, you can skip all of this since the environment is ready to go.
Getting Started: Project Setup
Before we dive into layouts and components, let’s review what you already have in the project.
The Backend Lives Under /app/api
If you look inside your project folder, you’ll notice this structure:
Everything under the app/api folder is backend-related. These files are API routes — special files that Next.js treats as endpoints for data instead of UI.
For example:
src/app/api/tasks/route.ts→ handles requests to/api/tasks(like “get all tasks” or “create a task”).src/app/api/tasks/[id]/route.ts→ handles requests to/api/tasks/1or/api/tasks/42(get, update, or delete a specific task).
Each of these files exports functions named after HTTP methods (GET, POST, DELETE, etc.). Next.js calls the right function when a request is made. The function then responds with JSON.
We won’t dive deep here because this was covered in the backend course, but just keep in mind: these routes are responsible for the data your frontend will use.
💡 Friendly Note: In this first lesson, you’ll see a lot of new concepts all at once — React components, layouts, props, hooks, Tailwind classes, and more. Don’t worry if you don’t fully understand every detail right away. The goal here is to get familiar with the fundamentals: how a Next.js app is structured, how layouts wrap pages, and how styling is applied.
You’ll have plenty of chances in later lessons and practices to revisit these ideas, apply them in code, and ask questions if something feels unclear. Think of this as laying the foundation — we’ll keep building on it step by step.
For this first pass, focus on two ideas: layouts wrap page content, and Tailwind classes style the elements. Treat hooks, active navigation, and route groups as a preview that we’ll revisit through practice.
React Components and .tsx Files
Outside of /app/api, everything you see in src/app is a React component.
For example, page.tsx and layout.tsx are both React components.
A React component is simply a function that:
- Can accept inputs (called props).
- Returns UI described in JSX.
JSX is an HTML-like syntax you can write directly inside JavaScript. For example:
This function returns <h1>Hello World</h1> as UI, and React takes care of rendering it in the browser.
Why the .tsx extension?
.tsx means TypeScript + JSX. TypeScript lets you add types (so your code is safer and easier to reason about), and JSX is what lets you write UI tags directly inside your code.
Layouts, children, and ReactNode
In Next.js, you’ll often see layout.tsx files. These are special React components that act as wrappers for your pages.
Here’s a simplified root layout:
Notice two things:
-
The children prop
childrenis a special prop in React. It represents whatever you put inside this component.
In this case, every page you write will be inserted where{children}appears. -
The ReactNode type
This is just TypeScript’s way of saying:childrencan be any valid React element (text, HTML, or other components).
Without this, TypeScript wouldn’t know what type of content to expect.
This is what makes layouts powerful. They give all your pages a shared structure (like headers, sidebars, or footers) without duplicating code.
How the App Is Structured Right Now
At this moment, your app is very simple:
page.tsx– the homepage (a single React component for the default route/).layout.tsx– the root layout that wraps every page with HTML structure.app/api/*– the backend API routes that provide data.
You’re starting from a minimal structure. In this lesson, we’ll expand it to add an app shell with navigation and consistent styling.
Building the Root Layout
The root layout is the top-level wrapper for your entire application. It’s where you can add global styles, scripts, and set up the basic HTML structure.
Here’s the code for src/app/layout.tsx:
Detailed Breakdown:
'use client';is required because this layout callsusePathname(), which is a client-side hook in the Next.js App Router.usePathname()is a Next.js hook that gives you the current URL path (e.g.,/tasks/123). We use it to highlight the active nav link.- The
<body>tag is styled with Tailwind classes:min-h-screen→ makes sure the body takes up the full screen height.bg-gray-50→ sets a light gray background.text-gray-900→ sets dark text.
{children}ensures that whatever page is being viewed will appear inside this layout.
This guarantees a consistent look across your whole app.
Styling with Tailwind CSS
For styling, we’re using Tailwind CSS. Tailwind is a utility-first CSS framework, which means instead of writing custom CSS rules, you apply small, single-purpose class names directly in your HTML or JSX.
For example:
bg-gray-50=background-color: #f9fafb;text-gray-900=color: #111827;min-h-screen=min-height: 100vh;p-4=padding: 1rem;rounded-md=border-radius: 0.375rem;
These classes are shortcuts that save you from writing custom CSS files. You just combine them to create the look you want.
In your layouts, Tailwind is used to quickly set up a responsive grid, style the sidebar, add hover effects on links, and give the header a subtle blur effect with backdrop-blur. Think of it as writing CSS “inline,” but with readable utility names instead of raw styles. This makes it much faster to prototype and keeps your code consistent.
Creating a Dashboard Layout with Navigation
Most apps need a navigation bar so users can move between pages. Let’s create a new layout for the “dashboard” part of the app. It will include:
- A sidebar with navigation links.
- A header at the top.
- A placeholder for notifications.
Here’s the code for src/app/(dashboard)/layout.tsx:
Detailed Breakdown:
usePathname()is a Next.js hook that gives you the current URL path (e.g.,/tasks/123). We use it to highlight the active nav link.isActivechecks if the current path matches a link. This is conditional rendering: if the condition is true, we render a highlighted style.
Architecture note: In this course, the whole dashboard layout is marked as a client component for simplicity. In larger production apps, you would often keep the layout as a server component and move only the active navigation into a small client component.
navItems.map(...)turns our array of navigation items into actual<Link>components. This avoids repeating code and makes it easy to add new items later.- The sidebar (
<aside>) is hidden on small screens (hidden md:block) and visible on larger ones. - The header (
<header>) sticks to the top when scrolling (sticky top-0). <ToasterProvider>is included now as a placeholder. Later, we’ll use it to show toast notifications like “Task created!” or “Error saving task.” Putting it here means all pages automatically support notifications.
Understanding Layouts vs. Pages
In Next.js, there are two main kinds of files that define your app’s structure: layouts and pages.
layout.tsxfiles define wrappers. They are like templates that surround your content. Layouts are reusable and provide consistency (shared headers, sidebars, navigation, styling, etc.).page.tsxfiles define pages. These are the actual screens or routes that users visit in the browser.
Let’s look at both in practice.
Example: Root Layout
Here:
- This layout wraps the entire app.
- It ensures that every page has the same HTML structure, background color, and text color.
{children}is the placeholder where the current page’s content will be inserted.
Example: Page File
Here:
- This is the default homepage (
/). - It uses
DashboardLayoutto wrap the content so the page gets navigation and styling. - It renders
DashboardPage(a component that shows some statistics and will be covered in detail in the next unit).
Why This Matters
- Layouts provide structure and are shared across multiple pages.
- Pages provide content and are what users actually see when they visit a route.
Think of it like this:
- Layouts = the frame of the house (walls, roof, rooms).
- Pages = the furniture inside each room.
Layouts stay mostly the same across your app, while pages change depending on where the user navigates.
Review and Next Steps
In this lesson, you built the foundation for your Next.js app. You explored the packages powering the project, learned how Tailwind CSS works, and saw how layouts structure your application. You also created both a root layout and a dashboard layout with navigation.
Key takeaways from this lesson:
- Packages like Next.js, React, TypeScript, and Tailwind are pre-installed, but you know how to install them locally if needed.
- Tailwind CSS is used for quick, utility-based styling without writing custom CSS files.
- Layouts (
layout.tsx) wrap your pages and provide shared structure. - The root layout defines the base HTML and styling.
- The dashboard layout adds navigation, a header, and a placeholder for notifications.
Next, you will begin connecting the frontend to your backend API, fetching task data, and displaying it in React components.
