Design with Code

Exercise 13

Create Pages and Routes

Build dynamic pages with file-based routing, create reusable components, and organize data with TypeScript interfaces.

What you'll learn

Key takeaways from this exercise

  • Understanding file-based routing and dynamic routes in Next.js
  • Creating TypeScript interfaces for structured data
  • Building reusable components with typed props
  • Using Array.map() and Array.find() for data operations
  • Customizing colors and fonts with CSS variables
  • Navigating between pages with the Link component

Introduction

With your Next.js project set up, it's time to build the actual weather app. In this exercise, you'll create the page structure, define your data, and learn how URLs work in a modern web application. This is where the app starts to take shape.

File-based routing

One of the most intuitive features of Next.js is routing — the system that determines which page to display based on the URL. In Next.js, routing is file-based: the files and folders inside your app/ directory directly map to URLs. A file at app/page.tsx becomes your home page at /. A file at app/about/page.tsx becomes /about. The file system is the router.

This gets more interesting with dynamic routes. Instead of creating a separate folder for every city in your weather app, you create a single folder with square brackets: app/[slug]/page.tsx. The [slug] part means "any value here" — so /london, /new-york, and /berlin all use the same page template but display different content. The slug (the value in the URL) gets passed to your page component as a parameter, and you use it to look up the right data.

Data and TypeScript

Speaking of data — where does it come from? For now, we'll use a local data file. You'll create an array of location objects, each with properties like name, slug, latitude, and longitude. This is the same pattern you used in Part 2 (separating content from presentation), just with more structured data.

TypeScript interfaces play an important role here. An interface defines the shape of your data — what properties an object must have and what types those properties are. When you define a Location interface with name: string and slug: string, TypeScript ensures every location in your array has those properties. If you miss one, you get an error before anything breaks.

To work with arrays of data in your UI, you'll use the same array methods from Part 2. map() transforms each item into a piece of UI — turning an array of locations into a list of cards. find() retrieves a single item — looking up a specific location by its slug to display on the detail page.

Layouts and navigation

Layouts are another powerful Next.js concept. A layout.tsx file wraps all pages at its level with shared UI — things like a header, navigation, or consistent spacing. Instead of repeating the same wrapper in every page file, you define it once in the layout and all pages inherit it. The children prop is where the page content appears.

For navigation between pages, Next.js provides the Link component, which enables fast, client-side navigation without full page reloads. Instead of <a href="/london">, you use <Link href="/london"> — it looks the same but performs much better.

What you'll have

By the end of this exercise, you'll have a working multi-page app: a home page listing all locations and individual location pages showing weather details. The data is still hardcoded (we'll connect to a real API in the next exercise), but the structure is solid — and it's the same structure used by production applications.

Create a free account to access the full course

In order to access full course content and track your progress, please sign in