简体   繁体   中英

API route not found in a Next.js App (The page could not be found)

I am working in a Next.js app, and I've create an api route to send emails.

Everthing is working in my development environment.

However, when I deployed to production I just receive a 404 - The page could not be found error as response for this api route.

I am not the creator of the project, I suspect the problem is in the npm command used to deploy.

I just created a file in 'pages/api' and include this: server.post('*', (req, res) => handle(req, res)); on the server.js file. Do I need to do anything else?

I am using Vercel to deploy.

These are my scripts in the package.json file:

"scripts": {
    "dev": "node index.js",
    "build": "NODE_ENV=production next build",
    "start": "node index.js",
    "export": "next export",
    "now-build": "next build && next export -o dist"
}

In local environment I am using npm start command.

My build command in production is npm run now-build

在此处输入图像描述

This is the index.js file:

const { setConfig } = require('next/config')
setConfig(require('./next.config'))

require('./server')

This is the server.js file:

const express = require('express');
const next = require('next');
const nextI18NextMiddleware = require('next-i18next/middleware').default;

const nextI18next = require('./i18n');

const port = process.env.PORT || 3007;
const app = next({ dev: process.env.NODE_ENV !== 'production' });
const handle = app.getRequestHandler();

(async () => {
  await app.prepare();
  const server = express();

  server.post('*', (req, res) => handle(req, res));

  server.use(nextI18NextMiddleware(nextI18next));

  server.get('*', (req, res) => handle(req, res));

  await server.listen(port);
  console.log(`> Ready on http://localhost:${port}`); // eslint-disable-line no-console
})();

This is my api route file in pages/api/send-email.js :

import sendEmail from '../../utils/sendEmail';

export default async (req, res) => {
  if (req.method === 'POST') {
    const { to, subject, html } = req.body;
    const response = await sendEmail({ to, subject, html });
    if (response.success) {
      return res.status(200).end();
    }
    return res.status(500).json(response);
  }
  return res.status(400).end();
};

This is how I am calling the api route:

    fetch('/api/send-email', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        to: formEmailTo,
        subject: formEmailSubject,
        html: FormEmailContent
      })
    })
      .then((response) => {
        if (!response.ok) {
          throw Error(response.statusText);
        }
        return response;
      })
      .then(() => handleOpenSnackbarMsg())
      .catch(() => handleOpenSnackbarErrMsg());

This is my next.config.js file:

const withCSS = require('@zeit/next-css')
const withImages = require('next-images');

module.exports = withImages(
  withCSS({
    exportTrailingSlash: true,
    exportPathMap: function() {
      return {
        '/': { page: '/' },
        '/blank-page': { page: '/blank-page' },
      };
    },
    publicRuntimeConfig: {
      localeSubpaths: typeof process.env.LOCALE_SUBPATHS === 'string'
        ? process.env.LOCALE_SUBPATHS
        : 'none',
    },
    webpack: (config, options) => {
      cssModules: true,
      //      config.module.rules.push({
      //          enforce: 'pre',
      //          test: /\.js?$/,
      //          exclude: [/node_modules/],
      //          loader: 'eslint-loader',
      //          options: {
      //            quiet: true,
      //          }
      //      });
      config.node = {
        fs: 'empty'
      }
      return config;
    },
  })
);

Thank you!

You cannot use next export if your project contains API routes. Remove next export from "now-build": "next build && next export -o dist" .

Reference: https://nextjs.org/docs/api-routes/introduction#caveats

Vercel does not support custom servers. You have to host it on a vps.

I think your problem was your framework preset which was set to "Other".

It should be "Next.js".

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM