3A. Build Hello Marsad with Next.js
Create, view, and verify your first Next.js App Router page in the Marsad Web App.
Build Hello Marsad with Next.js
Expected time: 15–20 minutes
Outcome: You can add a route to the Marsad Web App, understand which layout renders it, and verify a TypeScript change locally.
This is a local practice exercise. It deliberately avoids authentication, databases, APIs, queues, and service credentials. Keep this tutorial in the documentation, but remove the practice route before your first pull request unless your reviewer explicitly asks you to retain it.
1. Confirm the Web App Is Running
Follow either Run with Docker or Run Without Docker. Open http://localhost:3511 and confirm that the Marsad Web App loads.
If you used Docker Compose, edit files in the local main/ repository. Depending on the current Compose volume configuration, a source edit may require rebuilding or restarting main-app. Running yarn dev directly from main/ gives the fastest feedback for this exercise.
2. Create the Route
From the Marsad repository root, create this folder and file:
main/
└── src/
└── app/
└── (landing)/
└── tutorial/
└── hello-world/
└── page.tsxThe (landing) folder is a route group. It organizes code and applies the existing landing layout, but its name does not appear in the URL. The page will be available at /tutorial/hello-world.
Add this code to main/src/app/(landing)/tutorial/hello-world/page.tsx:
import type {Metadata} from 'next';
export const metadata: Metadata = {
title: 'Hello Marsad',
description: 'A first Next.js page created during developer onboarding.',
};
export default function HelloWorldPage() {
return (
<section className='container flex min-h-[60vh] flex-col items-center justify-center gap-4 px-4 text-center'>
<p className='text-sm font-medium uppercase tracking-wider text-primary'>
Developer Tutorial
</p>
<h1 className='text-4xl font-bold tracking-tight'>
Hello, Marsad!
</h1>
<p className='max-w-xl text-muted-foreground'>
Your first Next.js App Router page is running successfully.
</p>
</section>
);
}Do not add 'use client'. App Router pages are Server Components by default, and this page has no browser state, event handler, or browser-only API that requires a Client Component.
3. View the Page
Open http://localhost:3511/tutorial/hello-world.
You should see:
- the normal Marsad landing header and footer;
- the “Hello, Marsad!” heading;
- the tutorial label and supporting text; and
- “Hello Marsad” in the browser title.
The shared header and footer come from src/app/(landing)/layout.tsx. The route page supplies only the content between them.
4. Try Fast Refresh
Change the heading to include your name:
<h1 className='text-4xl font-bold tracking-tight'>
Hello, Marsad! I'm Sam.
</h1>Replace Sam with your name. Save the file and confirm that the browser updates without manually restarting the Next.js development server.
5. Verify the TypeScript
From main/, run:
npx tsc --noEmitThe command should exit successfully. Also inspect the practice diff:
git status --short
git diff -- src/app/\(landing\)/tutorial/hello-world/page.tsxIn PowerShell, quote the path if parentheses are interpreted by your shell:
git diff -- "src/app/(landing)/tutorial/hello-world/page.tsx"What You Just Learned
- A
page.tsxfile creates a route in the Next.js App Router. - Route groups such as
(landing)organize and wrap routes without changing their URLs. - Pages are Server Components unless they opt into client behavior.
- The nearest
layout.tsxsupplies shared page structure. - The
metadataexport controls page-specific browser and search metadata. - Marsad uses Tailwind utility classes for styling.
- Fast Refresh makes local UI iteration immediate.
Clean Up the Practice Route
Keep the hello-world/ practice route if you are continuing to 3C. Integrate a Hello Image Job; that tutorial extends this page with an interactive generator.
If you are stopping after this exercise, remove only the hello-world/ practice folder you created. Confirm with git status --short that no Hello Marsad application file remains. Do not remove the parent tutorial/ folder if it contains another developer's work.
If the team decides to keep the page, treat that as an explicit product change: validate it using the Web App's required checks and include it in a reviewed issue and pull request.
Checkpoint
You are ready to continue when you can explain why (landing) is absent from the URL, why the page does not need 'use client', and how the shared header and footer were added.