HackIndia Logo
HackathonsNewsSkillsGrowth
HackIndia LogoContact: +91 9910125804

General

  • Companies
  • Colleges
  • Board of Advisors
  • Brand Ambassadors
  • FAQ
  • Contact
  • Report a Bug

Hackathons

  • Upcoming Hackathons
  • Judges
  • Mentors
  • Partners
  • Participating Colleges
  • Testimonials

Resources

  • About Us
  • Branding
  • Latest News
  • Growth
  • Skills
  • Builders
  • Ecosystem
  • Forum
  • Ideas
  • Prompt Optimizer
  • Games

© 2026 HackIndia. All rights reserved.

Privacy PolicyTerms of ServiceCode of ConductSitemap

Build 2.139 · 05 Nov 2026, 10:27 UTC

    HackIndia
    HackathonsNewsInternshipsSkillsGrowthPro Perks
    ← Ship a Next.js App Router project

    All the reading

    Next.js

    7 lessons, about 30 minutes. The check's questions come from these.

    Contents
    Starting the App Router app
    1. 1. Start the App Router app
    2. 2. Map routes with files
    Using server and client components
    1. 3. Split server and client components
    2. 4. Fetch data on the server
    3. 5. Add an API route handler
    Preparing production and submission
    1. 6. Prepare for production
    2. 7. Submit the public repo

    Starting the App Router app

    1. Start the App Router app

    4 min

    In 30 seconds
    • Create a fresh Next.js App Router project with the current starter command.
    • Run it locally and know the files that make the first route work.
    • Make your first safe commit so your hackathon repo starts clean.
    Key point

    One idea

    Start with App Router from day one. In Next.js, routes come from files, and the app folder is where your project will grow.

    For this track, your repo must clearly show App Router files. Do not start with an older Pages Router tutorial and try to convert it at 2 am.

    What you create

    You will create a Next.js app using create-next-app. The current default setup gives you TypeScript, Tailwind CSS, ESLint, App Router, Turbopack, the @/* import alias, and AGENTS.md.

    You only need the starter today. Later lessons will add routes, Server and Client Components, server data fetching, and a route handler.

    Your to-do

    Before you start

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 4 done

    Example

    Create and run

    Use pnpm if you have it. This command creates the app with the default recommended choices, including App Router.

    The dev server runs locally. Open the local URL it prints in your browser.

    pnpm create next-app@latest campus-helpdesk --yes
    cd campus-helpdesk
    pnpm dev

    2. Map routes with files

    4 min

    In 30 seconds
    • Turn folders inside app into public routes.
    • Use page.tsx for screens and layout.tsx for shared UI.
    • Plan your hackathon app routes before adding features.
    Key point

    One rule

    In App Router, your URL comes from your files. A folder becomes a route only when it has a page.tsx file inside it.

    app/page.tsx is the home route /. app/team/page.tsx becomes /team. app/projects/new/page.tsx becomes /projects/new.

    What counts as a route

    Next.js uses file-system routing. You do not write a route table for normal pages.

    This is useful in hackathons. A judge or recruiter can open your repo and see your app structure quickly.

    Example

    Starter route map

    For a campus hackathon project, keep the first route map small. Add only the pages you can finish and test on a phone.

    Here is a simple structure for a student project showcase app.

    app/
      layout.tsx
      page.tsx
      about/
        page.tsx
      projects/
        page.tsx
        new/
          page.tsx
      contact/
        page.tsx

    Layouts wrap pages

    Using server and client components

    3. Split server and client components

    5 min

    In 30 seconds
    • Decide what stays on the server and what runs in the browser.
    • Add 'use client' only to small interactive components.
    • Pass simple props from Server Components to Client Components.
    Key point

    One split rule

    Keep pages and layouts as Server Components by default. Make a Client Component only when you need clicks, typing, state, effects, or browser APIs like window and localStorage.

    This keeps less JavaScript on the judge phone. It also keeps server-only code away from the browser.

    Default is server

    In the App Router, layouts and pages are Server Components unless you mark them otherwise. So app/page.tsx and app/dashboard/page.tsx can render UI without adding 'use client'.

    Server Components are good for reading files, calling a database later, and preparing data before the page reaches the browser. You will use that more in the next lesson.

    Your to-do

    Choose the side

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    Preparing production and submission

    6. Prepare for production

    4 min

    In 30 seconds
    • Run a production build and catch errors before judges do.
    • Choose a deployment type that supports your App Router features.
    • Test the deployed URL on a real phone and fix mobile breakage.
    Key point

    Production means real URL

    Your project is not ready when it works on localhost. It is ready when a judge can open a public URL on a phone and use the main flow.

    For this track, keep your App Router features working: layouts, Server Components, server fetches, and route handlers.

    Build before deploy

    A production build catches problems that dev mode may hide. Run it before every deployment, especially after adding a route handler or server-side data fetch.

    Next.js production scripts should include dev, build, and start. The build step prepares the app. The start step runs the production server locally.

    Example

    Package scripts

    10 questions, 7 to pass.

    Sign in to take the test

    Files to notice

    Open the project in your editor. The two files to notice today are app/layout.tsx and app/page.tsx.

    The root layout is required. It wraps your app. The page file creates the home route, which is /.

    Example

    Tiny home edit

    Make one small edit so your first commit is yours. Keep it simple.

    Replace the starter home content with a title for your hackathon idea. You will improve it later.

    // app/page.tsx
    export default function Home() {
      return (
        <main className="min-h-screen p-8">
          <h1 className="text-3xl font-bold">Campus Helpdesk</h1>
          <p className="mt-4">A Next.js App Router project for faster campus issue tracking.</p>
        </main>
      );
    }
    Common mistake

    Avoid old tutorials

    If a tutorial starts with a pages folder as the main router, it is using the older Pages Router path. Pages Router is still supported, but this track uses App Router.

    Also, older tutorials may talk like Webpack is the default. In the current starter, Turbopack is the default bundler. You do not need to change it today.

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    git init
    git add .
    git commit -m "Start Next.js App Router project"

    The root app/layout.tsx is required. It must contain html and body, and it receives children.

    A layout inside a folder wraps all pages below that folder. Use this for shared nav, sidebars, tabs, or a project dashboard shell.

    Example

    Root layout example

    This layout adds a simple header to every page. The children value is where the current route renders.

    // app/layout.tsx
    import type { ReactNode } from 'react';
    import './globals.css';
    
    export default function RootLayout({ children }: { children: ReactNode }) {
      return (
        <html lang="en">
          <body>
            <header>
              <a href="/">Home</a> | <a href="/projects">Projects</a> | <a href="/about">About</a>
            </header>
            <main>{children}</main>
          </body>
        </html>
      );
    }
    Your to-do

    Add one route

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Example

    Page example

    A page can be plain for now. Later lessons will add Server Components, Client Components, data fetching, and route handlers.

    // app/about/page.tsx
    export default function AboutPage() {
      return (
        <section>
          <h1>About this project</h1>
          <p>Built for a hackathon by a student team in India.</p>
        </section>
      );
    }
    Common mistake

    Common mistake

    Do not create only a folder and expect a URL to work. The route is accessible only when that segment has a page.tsx file.

    Also avoid copying older tutorials that put most routes in pages/. App Router uses the app folder for this track.

    Tip

    Plan before coding

    Ask AI for a route map, not for the full app. Give it your idea, user types, and demo flow. Then check that every important demo screen has a clear URL.

    For a 24-hour build, choose 4 to 6 routes. More routes means more testing before submission.

    Prompt:
    I am building a Next.js App Router hackathon app for [idea].
    Users are [students/admins/judges].
    Suggest a small app/ folder route map with 4 to 6 routes.
    Use page.tsx and layout.tsx only.
    Do not include API routes yet.
    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    0 of 5 done

    Example

    Server page, client button

    This example shows a hackathon project card rendered by a Server Component. Only the like button runs in the browser.

    // app/projects/page.tsx
    import LikeButton from '@/components/LikeButton'
    
    const project = {
      id: 'upi-splitter',
      name: 'UPI Splitter',
      team: 'Team NIT Weekend',
      likes: 12,
    }
    
    export default function ProjectsPage() {
      return (
        <main className="p-6">
          <h1 className="text-2xl font-bold">Projects</h1>
          <article className="mt-4 rounded border p-4">
            <h2 className="text-xl">{project.name}</h2>
            <p className="text-sm text-gray-600">{project.team}</p>
            <LikeButton initialLikes={project.likes} />
          </article>
        </main>
      )
    }
    
    // components/LikeButton.tsx
    'use client'
    
    import { useState } from 'react'
    
    type LikeButtonProps = {
      initialLikes: number
    }
    
    export default function LikeButton({ initialLikes }: LikeButtonProps) {
      const [likes, setLikes] = useState(initialLikes)
    
      return (
        <button
          className="mt-3 rounded bg-black px-4 py-2 text-white"
          onClick={() => setLikes(likes + 1)}
        >
          Like project ({likes})
        </button>
      )
    }
    Common mistake

    Do not client everything

    A common beginner move is adding 'use client' to app/layout.tsx or every page because one button needs useState. That sends more code to the browser than needed.

    Older tutorials may do this. In App Router, mark the smallest interactive component instead.

    Tip

    Use AI carefully

    If you ask an AI tool to build a component, tell it: “Use Next.js App Router. Keep the page as a Server Component. Put interactivity in a small Client Component.”

    Check the answer. 'use client' must be the first statement in the client file. The Server Component should not use useState, useEffect, onClick, window, or localStorage.

    Props must be simple

    You can pass data from a Server Component to a Client Component using props. But those props must be serializable by React.

    Good props: project name, initial count, list of tags. Bad props: functions, database clients, class instances, or secret values.

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    4. Fetch data on the server

    4 min

    In 30 seconds
    • Fetch data inside a Server Component with async and await.
    • Keep API keys and database queries off the browser bundle.
    • Render real project data in a page without useEffect.
    Key point

    Main idea

    In App Router, pages and layouts are Server Components by default. That means you can fetch data directly in the component before it renders.

    Use a route handler only when the browser or another service needs an API. For a normal page read, fetch on the server.

    Why server fetch

    A hackathon judge does not care where your data comes from. They care that the deployed page opens fast, shows real content, and does not leak secrets.

    Server-side fetching helps because your database query, API key, and filtering logic stay on the server. They are not shipped in the client JavaScript bundle.

    Your to-do

    Choose one data source

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 4 done

    Example

    Server page fetch

    This example creates a projects page that fetches data on the server. The page component is async, then it awaits fetch and renders the result.

    Replace the URL with your real API later. The shape of the data must match what you render.

    // app/projects/page.tsx
    type Project = {
      id: number
      name: string
      city: string
    }
    
    async function getProjects() {
      const res = await fetch('https://example.com/api/projects')
    
      if (!res.ok) {
        throw new Error('Failed to load projects')
      }
    
      return res.json() as Promise<Project[]>
    }
    
    export default async function ProjectsPage() {
      const projects = await getProjects()
    
      return (
        <main className="p-6">
          <h1 className="text-2xl font-bold">Student projects</h1>
          <ul className="mt-4 space-y-3">
            {projects.map((project) => (
              <li key={project.id} className="rounded border p-3">
                <p className="font-medium">{project.name}</p>
                <p className="text-sm text-gray-600">{project.city}</p>
              </li>
            ))}
          </ul>
        </main>
      )
    }
    Tip

    Ask AI well

    You can ask ChatGPT or Gemini to draft the fetch function and TypeScript type. Give it one sample JSON item and the page path.

    Check three things in the answer: no 'use client' at the top, the component is async, and errors are handled when the response is not ok.

    Common mistake

    Common wrong turn

    Many older tutorials fetch page data with useEffect and useState. That makes the browser wait, then fetch, then update the page.

    For App Router, start with server fetching. Move to a Client Component only when the user must click, type, filter, or use a browser API.

    Caching note

    Current Next.js docs say fetch requests are not cached by default. A fetch can block rendering until it finishes.

    For this lesson, keep it simple. Get the data rendering correctly first. Add caching or streaming later only when your app needs it.

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    5. Add an API route handler

    4 min

    In 30 seconds
    • Create an API endpoint inside app using route.ts.
    • Return JSON from GET or POST with Web Request and Response APIs.
    • Use route handlers only when the browser or another service needs an API.
    Key point

    One idea

    A route handler is a server endpoint made by adding route.ts inside the app folder. Use it when your browser UI, webhook, mobile client, or another service needs to call your app over HTTP.

    Do not create an API route for every database read. In App Router, Server Components can fetch data directly on the server.

    Where it fits

    Your pages use page.tsx. Your layouts use layout.tsx. Your API endpoint uses route.ts.

    The folder path becomes the URL. app/api/status/route.ts becomes /api/status. This is file-based routing, but for HTTP methods instead of screens.

    Example

    Simple GET route

    Add this file to your project. It returns JSON that your judge, frontend, or phone browser can open.

    // app/api/status/route.ts
    
    export async function GET() {
      return Response.json({
        ok: true,
        app: "HackIndia demo",
        message: "API route is working",
      });
    }
    Your to-do

    Test the route

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Example

    POST for form data

    Use POST when the browser sends data to your server. This example accepts a team name for a hackathon project and returns a small response.

    This does not save to a database yet. It proves that your app can receive JSON and respond from the server.

    // app/api/teams/route.ts
    
    type TeamRequest = {
      teamName?: string;
    };
    
    export async function POST(request: Request) {
      const body = (await request.json()) as TeamRequest;
    
      if (!body.teamName) {
        return Response.json(
          { error: "teamName is required" },
          { status: 400 }
        );
      }
    
      return Response.json({
        saved: true,
        teamName: body.teamName,
      });
    }
    Tip

    Use AI carefully

    You can ask ChatGPT, Gemini, or Claude to write a route.ts for your exact use case. Give it your folder path, method, expected request body, and expected response.

    Check three things in the answer: it exports GET or POST by name, it uses Request and Response APIs, and it does not put secret keys in client code.

    Common mistake

    Common mistake

    Beginners often fetch their own API route from a Server Component just to read server data. That adds an extra HTTP hop inside the same app.

    If only a page needs the data, fetch it directly in the Server Component. If a Client Component, form, webhook, or external app needs an endpoint, use route.ts.

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Your package.json should have scripts like this. If you used create-next-app, you will likely already have them.

    {
      "scripts": {
        "dev": "next dev",
        "build": "next build",
        "start": "next start",
        "lint": "eslint",
        "lint:fix": "eslint --fix"
      }
    }
    Your to-do

    Local production check

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Pick the right host

    Next.js can be deployed as a Node.js server, Docker container, static export, or through an adapter-supported host. Node.js server and Docker deployments support all Next.js features.

    Be careful with static export. It has limited feature support. For this project, you have server-side data fetches and a route handler, so choose a host that can run Next.js server features.

    Common mistake

    Localhost is not proof

    Do not submit only screenshots or a localhost URL. Judges cannot open your laptop from their phone.

    Also do not test only on your own desktop. Mobile layout, slow college Wi-Fi, and missing environment variables often fail only after deployment.

    Tip

    Ask AI for checks

    Use ChatGPT, Gemini, or Claude as a checklist helper, not as the final judge. Paste your package scripts, app folder tree, and deployment error.

    Ask it to find likely production issues. Then verify every suggestion against your terminal output and your deployed app. Do not paste secret keys.

    Prompt:
    I am preparing a Next.js App Router hackathon project for production.
    Here are my package scripts, app folder tree, and build error.
    Tell me the likely issue and the smallest safe fix.
    Do not suggest moving to Pages Router.
    Do not suggest exposing unprefixed environment variables to the client.
    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    7. Submit the public repo

    5 min

    In 30 seconds
    • Make your repo prove the App Router work without a long explanation.
    • Add a clear README with routes, server fetch, route handler, and live link.
    • Test the deployed URL on a phone before you submit.
    Key point

    Proof beats claims

    Judges and recruiters will not inspect every file deeply. Your repo should make the App Router evidence easy to find in under two minutes.

    Your submission must show file-based routes, layouts, Server and Client Components, one server-side data fetch, one route handler, and a deployed URL that works on a phone.

    Your to-do

    Final repo check

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 6 done

    Example

    README proof block

    Put a short proof section near the top of README.md. Do not make judges hunt through your project.

    Keep it factual. Link to the live app and list the exact files that prove each requirement.

    Project: Campus Mess Feedback
    
    Live URL: https://your-deployed-app.example
    
    Built with: Next.js App Router
    
    App Router proof:
    - File-based routes: app/page.tsx, app/feedback/page.tsx, app/admin/page.tsx
    - Shared layout: app/layout.tsx
    - Server Component: app/feedback/page.tsx
    - Client Component: app/components/RatingForm.tsx
    - Server-side data fetch: app/admin/page.tsx fetches feedback before render
    - Route handler: app/api/feedback/route.ts handles POST requests
    
    How to run locally:
    - Install dependencies
    - Run the dev script
    - Open the local URL printed in the terminal
    
    Phone test:
    - Tested the deployed URL on Android Chrome using mobile data
    - Main pages load
    - Feedback form submits
    - Admin page renders data
    Common mistake

    Common weak submission

    A weak repo only has a live link and a one-line README. That makes your work look unfinished even if the app runs.

    Another common mistake is submitting a localhost screenshot. Judges need a public deployed URL. Test it on a real phone because that is how many hackathon judges will open it.

    Tip

    Use AI carefully

    You can ask ChatGPT, Gemini, or Claude to review your README before submission. Paste your file tree and ask it to check whether each App Router requirement is visible.

    Do not blindly accept its answer. Verify the file names yourself. AI may claim a route handler exists when your file is actually named handler.ts instead of route.ts.

    Example

    AI review prompt

    Use a prompt like this after you finish the repo. It helps you catch missing proof before submission.

    You are reviewing my Next.js App Router hackathon repo README.
    Check if it clearly proves these requirements:
    1. File-based routes
    2. Layouts
    3. Server Components
    4. Client Components
    5. At least one server-side data fetch
    6. At least one route handler
    7. Public deployed URL tested on a phone
    
    Here is my README:
    [paste README]
    
    Here is my app folder tree:
    [paste app folder tree]
    
    Return only:
    - Missing proof
    - Confusing file names
    - README edits I should make
    Your to-do

    Submit checklist

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done

    Your to-do

    Do this now

    Do each one yourself, then tap it to tick it off. The ticks are only a checklist for you: they are not marked or scored.

    0 of 5 done