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

开启output: export时Next.js 13构建失败:缺少generateStaticParams()

Next.js 13 开启 output: export 后构建失败的解决思路

问题描述

开启 output: export 配置后,构建时触发以下错误:

Error: Page "/api/auth/[...nextauth]" is missing "generateStaticParams()" so it cannot be used with "output: export" config.
    at D:\Projects\Thanksgiving\front\IHL-frontend\node_modules\next\dist\build\index.js:969:59
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async Span.traceAsyncFn (D:\Projects\Thanksgiving\front\IHL-frontend\node_modules\next\dist\trace\trace.js:105:20)
    at async Promise.all (index 4)
    at async D:\Projects\Thanksgiving\front\IHL-frontend\node_modules\next\dist\build\index.js:862:17
    at async Span.traceAsyncFn (D:\Projects\Thanksgiving\front\IHL-frontend\node_modules\next\dist\trace\trace.js:105:20)
    at async D:\Projects\Thanksgiving\front\IHL-frontend\node_modules\next\dist\build\index.js:801:124
    at async Span.traceAsyncFn (D:\Projects\Thanksgiving\front\IHL-frontend\node_modules\next\dist\trace\trace.js:105:20)
    at async build (D:\Projects\Thanksgiving\front\IHL-frontend\node_modules\next\dist\build\index.js:185:29)
    at async main (D:\Projects\Thanksgiving\front\IHL-frontend\node_modules\next\dist\bin\next:157:5)

项目结构

- src
   middleware.js
- app
   favicon.ico
   globals.css
   layout.js
   loading.js
   page.js
  -- api
    --- auth
       baseaxios.js
      ---- [...nextauth]
         route.js
  -- assets
     loader.gif
  -- dislike
     layout.js
     page.js
    --- comments
      ---- [postid]
         Comment.module.css
         page.js
  -- forgot-password
     forgotPassword.module.css
     loading.js
     page.js
  -- like
     layout.js
     loading.js
     page.js
    --- comments
      ---- [postid]
         Comment.module.css
         page.js
  -- login
     loading.js
     login.module.css
     page.js
  -- password-change-confirm
     loading.js
     page.js
     PCC.module.css
  -- profile
     layout.js
     loading.js
     page.js
     Profile.module.css
  -- register
     loading.js
     page.js
     register.module.css
- components
   CheckWrapper.js
   Loader.js
   Posts.js
   Posts.module.css
   Provider.js
  -- AddPostButton
     PostButton.js
     PostButton.module.css
  -- Modals
     AddPost.js
     AddPost.module.css
  -- Query
     QueryProvider.js
  -- StatisticBar
     SBar.js
     SBar.module.css
- lib
   get-posts.js
   makeLike.js
   numberFormate.js
- pages
- redux
   ReduxProvider.js
   store.js
  -- features
     auth-slice.js
- schemas
   index.js

app/api/auth/[...nextauth]/route.js 代码

const BACKEND_REFRESH_TOKEN_LIFETIME = 90 * 24 * 60 * 60;
const SIGN_IN_HANDLERS = {
  "credentials": async (user, account, profile, email, credentials) => {
    return true;
  },
};
const SIGN_IN_PROVIDERS = Object.keys(SIGN_IN_HANDLERS);


export const authOptions = {

  providers: [
    CredentialsProvider({

      name: 'Credentials',

      credentials: {
        username: { label: "Email", type: "email", placeholder: "Email" },
        password: { label: "Password", type: "password", placeholder: "Password" }
      },
      async authorize(credentials, req) {
        try {
          const res = await axios.post("auth/login/", credentials, {
            headers: { "Content-Type": "application/json" }
          });

          const user = res.data; // Access the response data directly

          // If no error and we have user data, return it
          if (res.status === 200 && user && user.token && user.user) {
            return user;
          } else {
            throw new Error("Invalid response from authentication API");
          }

          // Return null if user data could not be retrieved
          return null;
        } catch (error) {
          // Handle error here
          return { error: "Invalid credentials" };
        }


      }
    }),

  ],

  callbacks: {
    async signIn({ user, account, profile, email, credentials }) {
      if (!SIGN_IN_PROVIDERS.includes(account.provider)) return false;
      return SIGN_IN_HANDLERS[account.provider](
        user, account, profile, email, credentials
      );
    },
    async jwt({ user, token, account }) {
      // If `user` and `account` are set that means it is a login event
      if (user && account) {
        let backendResponse = account.provider === "credentials" ? user : account.meta;

        if (backendResponse && backendResponse.user && backendResponse.token) {
          token["user"] = backendResponse.user;
          token["token"] = backendResponse.token;
        } else {
          throw new Error("Invalid backend response for JWT token generation");
        }

        return token;
      }

      return token;
    },

    async session({ token }) {
      return token;
    },
  },

  pages: {
    signIn: "/login",
  },

  session: {
    strategy: "jwt",
    maxAge: BACKEND_REFRESH_TOKEN_LIFETIME,
  },

}



const handler = NextAuth(authOptions);

export { handler as GET, handler as POST }

已尝试的方案

  • 迁移 authOptions 到其他目录
  • 将 Next.js 降级至 13.4.19 版本

解决思路

1. 核心原因

output: export 会生成纯静态HTML文件,不支持运行时API路由,而 [...nextauth] 是动态API路由,依赖服务器环境运行,因此构建时触发错误。

2. 方案一:抽离认证到独立后端

把NextAuth的认证逻辑迁移到单独的Node.js后端(如Express),前端通过HTTP请求调用后端完成认证流程,静态导出时不再包含认证API路由。

3. 方案二:改用纯前端JWT认证

放弃NextAuth的API路由模式,手动实现认证:

  • 在登录页直接调用后端登录接口获取JWT token
  • 将token存储在localStorage或HttpOnly Cookie中
  • 用middleware.js拦截页面请求,检查token有效性,未登录则跳转登录页
  • 所有需要认证的接口请求,手动在请求头中携带token

4. 方案三:放弃静态导出

如果必须保留NextAuth的API路由,只能取消output: export配置,改用Vercel、Netlify等平台部署,或自行搭建Node.js服务器运行Next.js应用。

5. 临时测试方案(功能会失效)

修改next.config.js添加以下配置,忽略认证API路由的构建,但静态导出后认证功能会完全不可用,仅适用于测试场景:

module.exports = {
  output: 'export',
  experimental: {
    outputFileTracingExcludes: {
      '*': ['**/api/auth/**']
    }
  }
}

内容的提问来源于stack exchange,提问作者Valerii Linden

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 14:48:10