You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何将Next.js旧版/pages目录代码迁移至新版/app目录

将Next.js Pages目录代码适配到App目录结构

一、调整目录结构

  • 删除原有的 /pages 目录
  • 在项目根目录新建 /app 目录
  • 在 /app 目录下创建两个核心文件:layout.tsx(替代原 _app.tsx)和 page.tsx(替代原 index.tsx)

二、迁移 _app.tsx 到 layout.tsx

原 _app.tsx 的核心作用是全局样式注入和上下文提供者包裹,适配后的 layout.tsx 代码如下:

'use client';
import "tailwindcss/tailwind.css";
import { DataProvider } from "../contexts/DataContext";
import React from 'react';

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

说明:

  • 添加 'use client' 指令,因为 DataProvider 是客户端上下文组件,需在客户端环境运行
  • RootLayout 必须包含 <html> 和 <body> 标签,这是App目录结构的强制要求

三、迁移 index.tsx 到 page.tsx

原 index.tsx 是首页组件,适配时需注意:添加 'use client' 指令(因使用了 useState 和自定义上下文钩子 useData),同时可选择两种方式处理页面元数据:

方式一:使用Metadata API(推荐)

用App目录原生的Metadata API替代原 next/head 组件:

'use client';
import { useState } from "react";
import Body from "../components/Body";
import Header from "../components/Layout/Header";
import { UploadImage } from "../components/UploadImage";
import { useData } from "../contexts/DataContext";

// 定义页面元数据,替代原Head组件
export const metadata = {
  title: "Decentragram",
  icons: {
    icon: "/favicon.ico",
  },
};

export default function Home() {
  let [isOpen, setIsOpen] = useState(false);
  const { loading } = useData();

  function closeModal() {
    setIsOpen(false);
  }

  function openModal() {
    setIsOpen(true);
  }

  return (
    <div className="flex flex-col items-center justify-start min-h-screen py-2">
      <UploadImage isOpen={isOpen} closeModal={closeModal} />
      <Header />
      <div
        className="max-w-2xl w-full bg-blue-100 rounded-xl flex justify-center items-center py-2 mt-3 hover:bg-blue-200 cursor-pointer"
        onClick={openModal}
      >
        <span className="text-blue-500 font-bold text-lg">Upload Image</span>
      </div>
      {loading ? (
        <div className="font-bold text-gray-400 mt-36 text-4xl">Loading...</div>
      ) : (
        <Body />
      )}
    </div>
  );
}

方式二:继续使用 next/head(兼容旧代码)

如果想保留原写法,直接在客户端组件中导入使用即可:

'use client';
import Head from "next/head";
import { useState } from "react";
import Body from "../components/Body";
import Header from "../components/Layout/Header";
import { UploadImage } from "../components/UploadImage";
import { useData } from "../contexts/DataContext";

export default function Home() {
  let [isOpen, setIsOpen] = useState(false);
  const { loading } = useData();

  function closeModal() {
    setIsOpen(false);
  }

  function openModal() {
    setIsOpen(true);
  }

  return (
    <div className="flex flex-col items-center justify-start min-h-screen py-2">
      <Head>
        <title>Decentragram</title>
        <link rel="icon" href="/favicon.ico" />
      </Head>
      <UploadImage isOpen={isOpen} closeModal={closeModal} />
      <Header />
      <div
        className="max-w-2xl w-full bg-blue-100 rounded-xl flex justify-center items-center py-2 mt-3 hover:bg-blue-200 cursor-pointer"
        onClick={openModal}
      >
        <span className="text-blue-500 font-bold text-lg">Upload Image</span>
      </div>
      {loading ? (
        <div className="font-bold text-gray-400 mt-36 text-4xl">Loading...</div>
      ) : (
        <Body />
      )}
    </div>
  );
}

四、验证适配结果

启动开发服务器:npm run dev,访问 http://localhost:3000,确认页面上传弹窗、加载状态、组件渲染等功能与原Pages目录版本一致。

内容的提问来源于stack exchange,提问作者Ahmed B

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 09:20:20