Adios

Hands-on Next.js tutorial

Build a Next.js app and deploy the working source.

Start with an empty folder. Finish with a responsive app, a health check, search metadata routes, a production manifest, a healthy Adios release, and a Git commit you can keep building.

Before you begin

Install Node.js 20 or newer, npm, Git, and the Adios CLI. You will also need an Adios account and a Git repository destination if you want to push the finished source.

01

Create the Next.js project

This command makes the choices explicit: TypeScript, Tailwind, ESLint, App Router, a src directory, the default import alias, and npm.

Terminal
npx create-next-app@latest ./my-project \
  --ts \
  --tailwind \
  --eslint \
  --app \
  --src-dir \
  --import-alias "@/*" \
  --use-npm

cd my-project
npm run dev

Open http://localhost:3000 and confirm the starter page loads. Stop the development server before continuing if you want to reuse the terminal.

02

Replace the starter page

Replace src/app/page.tsx with a small server-rendered page. Keeping metadata in the page makes the example complete without changing the generated root layout.

src/app/page.tsx
import type { Metadata } from "next";

export const metadata: Metadata = {
  title: "Northstar — A small app ready to ship",
  description:
    "A production-ready Next.js example with health and search metadata routes.",
};

const checks = [
  "Responsive App Router page",
  "Production health endpoint",
  "Sitemap and robots routes",
  "Repeatable Adios deployment",
];

export default function Home() {
  return (
    <main className="min-h-screen bg-slate-950 px-6 py-20 text-white">
      <div className="mx-auto max-w-5xl">
        <p className="text-sm font-semibold uppercase tracking-[0.18em] text-cyan-300">
          Next.js on Adios
        </p>
        <h1 className="mt-5 max-w-3xl text-5xl font-bold tracking-tight sm:text-7xl">
          Build the app. Keep the deployment clear.
        </h1>
        <p className="mt-6 max-w-2xl text-lg leading-8 text-slate-300">
          This project has the files a production release needs, from a health
          check to the runtime contract stored beside the source.
        </p>

        <div className="mt-12 grid gap-4 sm:grid-cols-2">
          {checks.map((check) => (
            <div
              key={check}
              className="rounded-xl border border-white/10 bg-white/5 p-5 text-base text-slate-200"
            >
              {check}
            </div>
          ))}
        </div>

        <a
          href="/api/health"
          className="mt-10 inline-flex rounded-lg bg-white px-5 py-3 font-semibold text-slate-950"
        >
          Check application health
        </a>
      </div>
    </main>
  );
}
03

Create the health route

Add src/app/api/health/route.ts. Adios will request this route before it promotes the candidate release.

src/app/api/health/route.ts
export function GET() {
  return Response.json({ status: "ok" });
}

Keep this route fast. If your application cannot serve traffic without a database or another required service, decide whether readiness should verify that dependency too.

04

Add sitemap and robots routes

Next.js metadata files generate the public /sitemap.xmland /robots.txt responses. The local fallback keeps development working; production should use the final public URL.

src/app/sitemap.ts
import type { MetadataRoute } from "next";

const siteUrl =
  process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000";

export default function sitemap(): MetadataRoute.Sitemap {
  return [
    {
      url: siteUrl + "/",
      lastModified: new Date(),
      changeFrequency: "weekly",
      priority: 1,
    },
  ];
}
src/app/robots.ts
import type { MetadataRoute } from "next";

const siteUrl =
  process.env.NEXT_PUBLIC_SITE_URL ?? "http://localhost:3000";

export default function robots(): MetadataRoute.Robots {
  return {
    rules: {
      userAgent: "*",
      allow: "/",
    },
    sitemap: siteUrl + "/sitemap.xml",
  };
}
05

Create adios.yaml in the project root

This file belongs beside package.json. It records how Adios should install, build, start, and check the current project.

adios.yaml
name: my-nextjs-app
region: de
replicas: 1

build_cmd: npm ci && npm run build
start_cmd: npm start

env:
  NEXT_PUBLIC_SITE_URL: https://replace-with-your-route.adios.run

runtime:
  name: node@24
  port: 3000
  health_path: /api/health
  memory_mb: 1024

Keep the placeholder hostname for the first deployment. Once Adios returns the generated route, replace it with the real HTTPS origin and deploy again so the sitemap contains the correct URL.

06

Run the production checks locally

A development page loading is not enough. Run the linter and the same production build the deployment will use.

Terminal
npm run lint
npm run build

If either command fails, fix the first error and rerun both checks before deploying.

07

Sign in and deploy the current source

Run the commands from the directory that contains adios.yaml. Review any requested permissions before allowing the deployment to continue.

Terminal
adios login
adios up

Adios uploads the current source, runs the build, starts the production process, checks /api/health, and returns a generated HTTPS route after the release is healthy.

08

Visit and verify the production app

Open the generated hostname and check all four responses:

  • / renders the new page.
  • /api/health returns {"status":"ok"}.
  • /robots.txt allows crawling and names the sitemap.
  • /sitemap.xml contains the public production URL.

Replace the placeholder NEXT_PUBLIC_SITE_URL value in adios.yaml with the generated hostname or your custom domain, run adios up again, and repeat the checks. Use Domains and Redirects when attaching a production hostname.

09

Review, commit, and push the working source

Review what changed before creating history. The diff should show the page, health route, search metadata routes, and manifest you just verified.

Terminal
git status
git diff
git add src/app/page.tsx src/app/api/health/route.ts \
  src/app/sitemap.ts src/app/robots.ts adios.yaml
git diff --cached
git commit -m "Build and deploy the Next.js app"
git remote -v
git push -u origin main

Confirm the remote and branch before the final command. If git remote -v is empty, create the remote repository first and add its URL as origin.

Finished project

Check the files before the next feature.

Expected files
my-project/
├── adios.yaml
├── package.json
├── package-lock.json
└── src/
    └── app/
        ├── api/
        │   └── health/
        │       └── route.ts
        ├── page.tsx
        ├── robots.ts
        └── sitemap.ts

Common problems

Why does the Next.js app need a health route?

Adios uses the health route to confirm that the production process is ready before it promotes the release. Keep the response fast and return a successful status only when the app can serve traffic.

Why do I need to replace the site URL after the first deploy?

A sitemap needs absolute production URLs. The first Adios deployment creates the generated hostname, so replace the placeholder in adios.yaml with that hostname and deploy once more before treating the sitemap as final.

What if npm run build fails?

Fix the local production build before deploying. Start with the first error, confirm the Node version and lockfile, and do not use a successful development server as proof that the production build works.

What if the release starts but never becomes healthy?

Confirm package.json has a start script that runs next start, the app listens on port 3000, and adios.yaml uses the same port and /api/health path. Then inspect the runtime logs for the first startup or health-check error before deploying again.

What if the project does not have a Git remote?

Create an empty repository with your Git provider, add it as origin, confirm the branch name, and then push. Do not run the example push command until git remote -v shows the destination you expect.

Keep building

Use the same contract with an AI coding agent.

The AI guide turns these exact files and checks into prompts for Codex, ChatGPT, Gemini, and Claude.

Open the AI workflow

Already have a Next.js repository?

Review the runtime details, official templates, pricing, and production checks on the deployment page.

Review Next.js deployment