Having trouble with Nextjs API Integration - encountering error 404

I'm currently facing a major issue and I've hit a dead end. I've been spending days trying to connect my local nextjs 14 app to the CVENT API, but I keep receiving a persistent 404 error. Here's what is displayed in the frontend console:

Here is the link to the CVENT documentation:

[Fast Refresh] rebuilding page.tsx:12 GET http://localhost:3000/api/cvent-api 404 (Not Found) eval @ page.tsx:12 Show 94 more frames page.tsx:29 API error: Error: HTTP error! status: 404 at eval (page.tsx:15:17) eval @ page.tsx:29 Promise.catch (async)
eval @ page.tsx:28 Show 97 more frames

.env.local:

# For server-side
CVENT_CLIENT_ID="hereGOEStheID"
CVENT_CLIENT_SECRET="heGoestheSecretID"
CVENT_SCOPE=event/events:read
NEXT_PUBLIC_API_HOSTNAME="https://api-platform-eur.cvent.com"

Api/cvent-api.ts:

import type { NextApiRequest, NextApiResponse } from 'next';
import fetch from 'node-fetch'

const baseUrl = 'https://api-platform-eur.cvent.com';

async function getAccessToken(): Promise<string> {
  const encodedCredentials = Buffer.from(`${process.env.CVENT_CLIENT_ID}:${process.env.CVENT_CLIENT_SECRET}`).toString('base64');
  const authHeader = `Basic ${encodedCredentials}`;

  // Ensure that client_id is defined or provide a fallback empty string to avoid undefined values
  const clientId = process.env.CVENT_CLIENT_ID || '';

  // Correctly format data for POST request
  const params = new URLSearchParams({
    grant_type: 'client_credentials',
    client_id: clientId,
  });

  const response = await fetch(`${baseUrl}/ea/oauth2/token`, { // Use base URL without appending client_id or scopes in the URL
    method: 'POST',
    headers: {
      Authorization: authHeader,
      'Content-Type': 'application/x-www-form-urlencoded',
    },
    body: params.toString(),
  });

  if (!response.ok) {
    throw new Error(`Error fetching access token, status: ${response.status}`);
  }

  const data = await response.json();
  return data.access_token;
}

// Handler function for the API route
export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  try {
    // Obtain a new access token
    const accessToken = await getAccessToken();
    console.log(`access token is: ${accessToken}`)

    // Make API call to Cvent to get attendees list
    const response = await fetch(`${baseUrl}/ea/attendees`, {
      method: "GET",
      headers: {
        "Content-type": "application/json",
        Authorization: `Bearer ${accessToken}`,
      }
    });

    if (!response.ok) {
      throw new Error(`Error fetching attendees list, status: ${response.status}`);
    }

    const data = await response.json();
    console.log('Data is:', data);
    res.status(200).json(data);
  } catch (error) {
    console.error(error);
    res.status(500).json({ message: 'Internal Server Error' });
  }
}

page.tsx:

"use client";
import React, { useState, useEffect } from "react";

const IndexPage = () => {
  const [connectionStatus, setConnectionStatus] = useState<string | null>(null);
  const [data, setData] = useState<any[]>([]); // Adjust the type based on your response structure
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  useEffect(() => {
    setIsLoading(true);
    fetch("/api/cvent-api") // Corrected URL
      .then((response) => {
        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }
        return response.json();
      })
      .then((responseData) => {
        setData(responseData);
        console.log("API response:", responseData);
        if (responseData && responseData.length > 0) {
          setConnectionStatus("Connection successful and attendees fetched!");
        } else {
          setConnectionStatus("Connection successful but no attendees found.");
        }
      })
      .catch((error) => {
        console.error("API error:", error);
        setError(error.toString());
        setConnectionStatus(`Failed to fetch: ${error.toString()}`);
      })
      .finally(() => setIsLoading(false));
  }, []);

  return (
    <div>
      <h1>Connection Status</h1>
      {isLoading && <p>Loading...</p>}
      {error && <p>{error}</p>}
      {connectionStatus && <p>{connectionStatus}</p>}
      {data && data.length > 0 && (
        <ul>
          {/* Adjust the rendering logic based on your response data */}
          {data.map((attendee) => (
            <li key={attendee.id}>{attendee.name}</li>
          ))}
        </ul>
      )}
    </div>
  );
};

export default IndexPage

Answer №1

It seems like you're utilizing the app router (you referenced v14 and have a "page.tsx") but the API handler you've exposed is for a pages router API handler.

To expose an API endpoint using the app router, you'll need to adhere to a different convention. In your scenario, consider creating a file at app/api/cvent-api/route.ts. Within this file, create a function named GET that takes in a parameter of type Request.

Check out https://nextjs.org/docs/app/building-your-application/routing/route-handlers for more information.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Encountering a snag when trying to load JavaScript within an HTML document

I encountered an error while trying to load an HTML file in the JavaScript console of the Brave browser. The error message reads: require.js:5 Uncaught Error: Module name "constants.js" has not been loaded yet for context: _. Use require([]) https://requir ...

After integrating NextAuth with my NextJS application, I encountered an issue when transitioning my app from the default localhost root to a basePath

Check out my next.config.js file /** @type {import('next').NextConfig} */ const basePath = process.env.NEXT_PUBLIC_BASE_PATH; const nextConfig = { reactStrictMode: true, swcMinify: true, basePath: `${basePath}`, assetPrefix: `${bas ...

Consider pushing items onto an array only once when the condition is met, instead of adding to the array every

I have been tasked with importing Excel files containing customer orders into my web application. The process involves converting the data in the file into an object of arrays, where each array represents a row from the Excel sheet. Once the data is impor ...

Sentry is causing issues with the build of my Next.js application

After integrating Sentry into my Next.js project, I have encountered an error that is preventing the application from building. The same error also occurs at runtime, but what confuses me is why it's affecting the build process. Is there a way to conf ...

What is the best way to link the data from the HTML input to the class property in the TypeScript file? (Combining Angular and IntroJs)

I'm working on an onboarding screen with Intro.js and need help with receiving user input. I've been trying different methods like [(ngModel)] = checked, [(checked)] = checked, (checked) = checked, but haven't had any success. Can anyone pro ...

Return either a wrapped or base type based on the condition

I am a beginner in TypeScript and I'm struggling to find the right combination of search terms to solve my issue. It seems like using a type condition could be helpful, but I still need to grasp how they function. My goal is to pass a function that p ...

Sorting through an array of objects using a filter method

While following a tutorial, I decided to make some changes to the TypeScript for learning purposes. However, I encountered a problem when trying to create a filter function from a React context script. I have successfully implemented a function called get ...

Is it possible to import the identical file twice consecutively using html and typescript?

I encountered an issue with an input element in my HTML file. Here's what it looks like: <input type="file" (change)="receiveFile($event)" id="inputFileButton" hidden /> This input element is designed for users to import files. Wh ...

Is there a way to make PrismaClient return DateTime fields as Unix timestamps rather than JavaScript date objects?

When utilizing the PrismaClient for database interaction, DateTime fields are returned as JavaScript Date objects instead of Unix timestamp numbers. Despite being stored as Unix timestamp numbers in the database itself, I require the dates to be retrieved ...

Issue encountered while implementing a recursive type within a function

I've created a type that recursively extracts indices from nested objects and organizes them into a flat, strongly-typed tuple as shown below: type NestedRecord = Record<string, any> type RecursiveGetIndex< TRecord extends NestedRecord, ...

Unable to retrieve a property from a variable with various data types

In my implementation, I have created a versatile type that can be either of another type or an interface, allowing me to utilize it in functions. type Value = string | number interface IUser { name: string, id: string } export type IGlobalUser = Value | IU ...

Setting up a custom PrimeNG theme to match our unique style is a great way to

I am currently using the most recent version of "primeng": "^12.2.0", and I am looking to implement my own custom theme for primeng. Despite searching through numerous blogs, I have yet to find a solution. In an attempt to create my cu ...

Inversify: class-based contextual dependency injection

I am currently experimenting with injecting loggers into various classes using inversify. My goal is to pass the target class name to the logger for categorization. The challenge I'm facing is the inability to access the target name from where I am c ...

What causes the NavBar to show and hide within a specific range?

Recently, I encountered a perplexing issue with my navbar. It functions correctly except for one strange behavior that has left me baffled. Why does the menu appear when I adjust the width to 631px, but disappear at 600px? And vice versa – why does it wo ...

Unit Testing AngularJS Configuration in TypeScript with Jasmine

I'm in the process of Unit Testing the configuration of a newly developed AngularJS component. Our application uses ui-router for handling routing. While we had no issues testing components written in plain Javascript, we are encountering difficulties ...

Updating an image without modifying the URL does not result in the image being updated

Currently, I am using Next.js 14 and have it hosted on Vercel. My database is set up with Supabase, and for DNS management, I rely on Cloudflare. The website I run contains images, and the image URLs are fetched from my Supabase DB. Typically, these URLs ...

Express encounters difficulty in processing Chunked Post Data

I am currently retrieving data from a Campbell Scientific data logger. This data is being posted to an application that is coded in Typescript using Express and BodyParser. The request successfully reaches the app (as I'm able to debug it), however, t ...

Guide to implementing fullpagejs with Angular 7 selectors

I have been working on an Angular 7 project with fullpagejs by Alvarotrigo. Everything seems to be functioning properly, but I am facing an issue where the content of my website is not visible because the color of fullpagejs covers it all. When I use norma ...

Troubleshooting issue of incorporating hintText in a TextField within a create-react-app-with-typescript

After recently downloading, installing, and running the create-react-app-with-typescript, I have been exploring different components. My latest experiment involved adding a TextField with hintText using the following code: import TextField from 'mate ...

Encountering a Nextjs net::ERR_ABORTED 404 error while accessing the production server configured with

After successfully building and deploying my app locally without any errors, I encountered a frustrating issue when deploying it on the server. Every static file accessed at /_next/static/ resulted in a net::ERR_ABORTED 404 error. While the pages' HTM ...