Rachel Tucker
Rachel Tucker

Reputation: 261

No HTTP methods exported in '...'. Export a named export for each HTTP method

I'm working on a React.js/Next.js project that utilizes Google reCAPTCHA. My frontend seems to be working (I know because I've set up print statements along the way), but the backend is giving me this error in my local terminal:

error - No HTTP methods exported in 'src\app\api\recaptcha\route.ts'. Export a named export for each HTTP method.

I'm also getting an error in my dev tools:

'POST http://localhost:3000/api/recaptcha 405 (Method Not Allowed)'

Which I believe is related to the other error.

Here is the code:

import { NextApiRequest, NextApiResponse } from 'next';
import express from 'express';
import cors from 'cors';
import bodyParser from 'body-parser';
import axios from 'axios';

const app = express();
app.use(cors());
app.use(bodyParser.json());

console.log('hi');

export async function postHandler(req: NextApiRequest, res: NextApiResponse){

  if (req.method === 'POST') {
    const { token } = req.body;
    try {
      const response = await axios.post(
      `https://www.google.com/recaptcha/api/siteverifysecret=${process.env.NEXT_PUBLIC_RECAPTCHA_SECRET_KEY}&response=${token}`
      );

      console.log('you made it here');

      if (response.data.success) {
        res.status(200).json({ message: 'reCAPTCHA verification successful' });
      } else {
        res.status(400).json({ message: 'reCAPTCHA verification failed' });
      }
    } catch (err) {
      console.log(err);
      res.status(500).json({ message: 'Internal server error' });
    }
  };
}

I've tried renaming the function, exporting it as const, and exporting at the end of the file rather than when it's named.

Upvotes: 26

Views: 43997

Answers (2)

Youssouf Oumar
Youssouf Oumar

Reputation: 46151

With the app folder/router (used when you answer yes to the last question shown in the below image), API Route Handlers should be defined as export async function METHOD() {}, where METHOD can be GET, POST, PUT, etc.

enter image description here

For example:

// app/api/route.js

import { NextResponse } from "next/server";

// Handles GET requests to /api
export async function GET(request: Request) {
  // ...
  return NextResponse.json({ message: "Hello World" });
}

// Handles POST requests to /api
export async function POST(request: Request) {
  // ...
  return NextResponse.json({ message: "Hello World" });
}

Upvotes: 26

udoyhasan
udoyhasan

Reputation: 2096

If you are using NextJS 13 App Router then use this code below:
File: ./app/api/recaptcha/route.ts

import { NextResponse } from 'next/server';
import axios from 'axios';

export async function POST(req: Request){
  const { token } = req.body;
  try {
    const response = await axios.post(`https://www.google.com/recaptcha/api/siteverify?secret=${process.env.NEXT_PUBLIC_RECAPTCHA_SECRET_KEY}&response=${token}`,{},{headers: { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" }});
    if (response.data.success) {
      return NextResponse.json({ message: 'reCAPTCHA verification successful' })
    } else {
      return NextResponse.json({ message: 'reCAPTCHA verification failed' })
    }
  } catch (err) {
    return NextResponse.json({ message: 'Internal server error' })
  }
}

If you are using NextJs 13 Page Router then use this:
File: ./pages/api/recaptcha.ts

import { NextApiRequest, NextApiResponse } from 'next';
 
const handler = async (req: NextApiRequest, res: NextApiResponse) => {
  if (req.method === 'POST') {
    const { token } = req.body;
    try {
      const response = await axios.post(`https://www.google.com/recaptcha/api/siteverify?secret=${process.env.NEXT_PUBLIC_RECAPTCHA_SECRET_KEY}&response=${token}`,{},{headers: { "Content-Type": "application/x-www-form-urlencoded; charset=utf-8" }});
      if (response.data.success) {
        return res.status(200).json({ message: 'reCAPTCHA verification successful' })
      } else {
        return res.status(400).json({ message: 'reCAPTCHA verification failed' })
      }
    } catch (err) {
      return res.status(500).json({ message: 'Internal server error' })
    }
  }
  else{
    res.status(405).json({message: "Method Not Allowed"})
  }
};
 
export default handler;

Hopefully this will fix your issues :)

Upvotes: 32

Related Questions