# How to Enable Next.js App Router Features in OpenMAIC

> Learn how to enable Next.js App Router in OpenMAIC by configuring next.config.js. Migrate pages and leverage Server Components for enhanced performance.

- Repository: [MAIC/OpenMAIC](https://github.com/THU-MAIC/OpenMAIC)
- Tags: how-to-guide
- Published: 2026-08-31

---

**Enable the App Router in OpenMAIC by setting `appDir: true` in [`next.config.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/next.config.js), then migrate your pages to an `app/` directory while using Server Components and the `next/navigation` APIs.**

OpenMAIC is a Next.js-based repository (as indicated by the [`vercel.json`](https://github.com/THU-MAIC/OpenMAIC/blob/main/vercel.json) configuration) that can leverage the modern App Router architecture for improved performance and developer experience. The App Router introduces Server Components, Server Actions, and file-based routing under the `app/` directory. This guide walks through the configuration changes and code patterns required to activate these features in the THU-MAIC/OpenMAIC codebase.

## Configure the Next.js App Router

The foundation of the migration starts with enabling experimental flags in your Next.js configuration.

### Enable the Experimental appDir Flag

Create or update [`next.config.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/next.config.js) at the repository root to activate the App Router. This file controls which experimental features the Next.js compiler recognizes.

```javascript
/** @type {import('next').NextConfig} */
const nextConfig = {
  experimental: {
    // Enable the App Router (app/ directory)
    appDir: true,
    // Optional: Enable Server Actions for direct server-side mutations
    serverActions: true,
  },
  reactStrictMode: true,
};

module.exports = nextConfig;

```

The `appDir` flag instructs Next.js to treat the `app/` directory as the source of truth for routing and rendering. When enabled, the framework switches from the legacy Pages Router to the new React Server Components architecture.

## Reorganize Your Project Structure

Once the configuration is active, you must establish the `app/` directory structure that the App Router expects.

### Create the Root Layout

Every App Router application requires a root layout at [`app/layout.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/app/layout.tsx). This Server Component wraps all pages and persists across navigation.

```tsx
export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head>
        <title>OpenMAIC</title>
      </head>
      <body>{children}</body>
    </html>
  );
}

```

The root layout replaces the traditional [`_app.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/_app.js) and [`_document.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/_document.js) files from the Pages Router. It runs on the server by default, allowing you to inject global metadata and structure without shipping JavaScript to the client.

### Implement Server Components

Pages inside `app/` are Server Components by default, meaning they execute exclusively on the server. This enables direct data fetching without exposing API keys or credentials to the browser.

```tsx
// app/page.tsx
async function fetchCourses() {
  // Direct backend call; environment variables stay server-side
  const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/courses`);
  return res.json();
}

export default async function HomePage() {
  const courses = await fetchCourses();

  return (
    <main>
      <h1>OpenMAIC Courses</h1>
      <ul>
        {courses.map((c: any) => (
          <li key={c.id}>{c.title}</li>
        ))}
      </ul>
    </main>
  );
}

```

Because this component runs on the server, the `fetchCourses` function never appears in the client bundle. This pattern eliminates the need for `getServerSideProps` or API route intermediaries required in the Pages Router.

## Update Navigation and Data Fetching Patterns

The App Router replaces the legacy `next/router` with a new navigation system optimized for concurrent features.

### Use the next/navigation API

Client components must import `useRouter` from `next/navigation` rather than `next/router`. The new API provides optimized prefetching and state management for the App Router architecture.

```tsx
'use client';
import { useRouter } from 'next/navigation';

export default function NavButton() {
  const router = useRouter();

  return (
    <button onClick={() => router.push('/course/123')}>
      Open Course 123
    </button>
  );
}

```

Other exports from `next/navigation` include `usePathname`, `useSearchParams`, and the `redirect` function for server-side navigation handling. These tools replace the imperative router patterns from previous Next.js versions.

## Ensure TypeScript Compatibility

The existing [`tsconfig.json`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tsconfig.json) in the OpenMAIC repository already includes the `next` TypeScript plugin, which provides automatic type definitions for App Router APIs. Verify that your `compilerOptions.plugins` array contains `"next"` to ensure proper IntelliSense for [`layout.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/layout.tsx) files and Server Component types.

According to the repository source, keeping this configuration updated prevents type errors when importing from `next/navigation` or defining async page components.

## Configure Vercel Deployment

The repository's [`vercel.json`](https://github.com/THU-MAIC/OpenMAIC/blob/main/vercel.json) already specifies the `nextjs` framework, ensuring Vercel's build pipeline recognizes the project type. However, confirm that your deployment environment uses Next.js 13 or later, as the App Router became stable in version 13.4.

After pushing changes with `appDir` enabled, Vercel automatically detects the `app/` directory and adjusts the build process to support React Server Components and streaming SSR. No additional platform configuration is required beyond the standard Next.js framework detection.

## Summary

- **Enable `appDir`** in [`next.config.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/next.config.js) to activate the App Router and Server Components architecture.
- **Create an `app/` directory** with [`layout.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/layout.tsx) and [`page.tsx`](https://github.com/THU-MAIC/OpenMAIC/blob/main/page.tsx) files to define your root structure and routes.
- **Migrate data fetching** directly into Server Components, removing the need for `getServerSideProps` or client-side fetch wrappers.
- **Update navigation logic** to use `next/navigation` instead of `next/router` for client components.
- **Leverage TypeScript support** already present in the repository's [`tsconfig.json`](https://github.com/THU-MAIC/OpenMAIC/blob/main/tsconfig.json) for full type safety across the new APIs.

## Frequently Asked Questions

### What is the difference between the Pages Router and App Router in OpenMAIC?

The Pages Router relies on a `pages/` directory where every file becomes a route rendered as a client-side React component. The App Router uses an `app/` directory where components default to Server Components, executing only on the server to reduce JavaScript bundles and improve initial page loads. OpenMAIC benefits from the App Router's ability to fetch data directly in components without exposing backend logic to the browser.

### Do I need to rewrite all my existing pages to use the App Router?

No, Next.js supports incremental adoption. You can maintain existing pages in the `pages/` directory while gradually migrating specific routes to the `app/` directory. Routes in `app/` take precedence over conflicting paths in `pages/`, allowing you to migrate feature-by-feature without a complete rewrite.

### How do Server Actions work with the App Router in OpenMAIC?

Server Actions allow you to define asynchronous functions that run on the server and can be invoked from client components. Enable them by setting `experimental.serverActions: true` in [`next.config.js`](https://github.com/THU-MAIC/OpenMAIC/blob/main/next.config.js). You can then mark functions with the `'use server'` directive, enabling form submissions or mutations without manually creating API endpoints in `pages/api/`.

### Will enabling appDir break my existing Vercel deployment?

No, the existing [`vercel.json`](https://github.com/THU-MAIC/OpenMAIC/blob/main/vercel.json) configuration already identifies the project as a Next.js application. Enabling `appDir` triggers the standard App Router build pipeline on Vercel, which supports both Server Components and streaming. Ensure your project uses Next.js 13.4 or later before deploying App Router features to production.