0

I have a Next.js application that has React components in the pages directory that render as expected. The application was built for a rails backend api and is using that backend every day properly. I am trying to add a twilio video chat to the app. I created an /api directory as instructed in all documentations. When I attempt to make a call to this api for literally a mock example to test the api I get the error in the terminal Error: The default export is not a React Component in page: "/api/twilio" at Object.renderToHTML (/home/application_in_question/node_modules/next-server/dist/server/render.js:117:19) and I also get Failed to load resource: the server responded with a status of 500 (Internal Server Error) in the browser. I was not part of the team that built this application so I am unsure of why I cannot add this Next.js api. The api is the selling point of Next and it is supposedly built into the framework.

I get this error is I just put the route in the address bar of the browser but I also get it from a file api call.

pages/twilio/index.js

  const handleFetchPosts = async () => { 
  debugger
  const tokenResponse = await fetch("/api/twilio"); 
  debugger
  const tokenData = await tokenResponse.json(); 
  debugger
  setToken(tokenData);
  }; 

section of package.json

"next": "^8.1.0",
"next-auth": "^1.8.5",
"next-compose-plugins": "^2.2.0",
"next-redux-wrapper": "^2.0.0",
"next-routes": "^1.4.2",
"next-seo": "^1.11.2",
"node-sass": "^4.12.0",

pages/api/twilio/index.js

console.log("running api")
const handler = (req, res) => {
    return res.json({ hello: 'world!' });
  };
  export default handler;

next.config.js

 const { withPlugins, optional } = require('next-compose-plugins')
// eslint-disable-next-line import/no-extraneous-dependencies
const { PHASE_PRODUCTION_BUILD } = require('next-server/constants')
const sass = require('@zeit/next-sass')
const { requireEnvVar } = require('./lib/utils')


  Custom Next.js Configuration
  @see https://nextjs.org/docs#custom-configuration

 const nextConfig = {

  Runtime configuration
  @see https://nextjs.org/docs#exposing-configuration-to-the-server--client-side

  publicRuntimeConfig: {
// Will be available on both server and client
    apiUrl: requireEnvVar('API_SERVER'),
    googleApiKey: requireEnvVar('GOOGLE_API_KEY'),
    stripeApiKey: requireEnvVar('STRIPE_PUBLISHABLE_KEY'),
    instantPayFee: requireEnvVar('INSTANT_PAY_FEE'),
  },

   Disable file-system routing
  @see https://nextjs.org/docs#disabling-file-system-routing
 
  **useFileSystemPublicRoutes: true,**

    Custom webpack config
    @see https://nextjs.org/docs#customizing-webpack-config

   webpack(config, { webpack }) {

  Only load specific locales for moment.js
  @see https://stackoverflow.com/a/25426019/956688
 
    config.plugins.push(
      new webpack.ContextReplacementPlugin(/moment[/\\]locale$/, /en/)
    )

    return config
  },
}


     Load multiple plugins with next-compose-plugins
     @see https://github.com/cyrilwanner/next-compose-plugins

    module.exports = withPlugins(
      [
        [sass],

      Analyzing the webpack bundle
         @see https://github.com/zeit/next-plugins/tree/master/packages/next-bundle-analyzer
 
       Load @zeit/next-bundle-analyzer as an optional plugin only during production build
       @see https://github.com/cyrilwanner/next-compose-plugins#optional-plugins
       @see https://github.com/cyrilwanner/next-compose-plugins#phases-array
 
        [
      // eslint-disable-next-line global-require,import/no-extraneous-dependencies
      optional(() => require('@zeit/next-bundle-analyzer')),
      {
    analyzeServer: ['server', 'both'].includes(process.env.BUNDLE_ANALYZE),
        analyzeBrowser: ['browser', 'both'].includes(
          process.env.BUNDLE_ANALYZE
        ),
        **bundleAnalyzerConfig: {
          server: {
            analyzerMode: 'static',
            reportFilename: '../../bundles/server.html',
          },
          browser: {
            analyzerMode: 'static',
                reportFilename: '../bundles/client.html',
              },
            }**,
          },
          [PHASE_PRODUCTION_BUILD],
        ],
      ],
  nextConfig
)`

As you can see above the team before me had useFileSystemPublicRoutes set to false. I have made this true.

When I attempt to fetch the api in the react page or use a get request in the browser for the api/index.js file I created with the code

`

 console.log("running api")
                                                                                           
const handler = (req, res) => {

    return res.json({ hello: 'world!' });
    };
    export default handler;` 

This gives the error above. This is a very simple example that I have seen work in numerous resources online so I do not understand why this is happening.

How can I get this api to work???

** I added the ** in an attempt to highlight the parts I think could help. I already set useFileSystemPublicRoutes to true.

Randy
  • 21
  • 3
  • where is that api file in your project folder structure? – tromgy Nov 17 '21 at 22:01
  • I have it in the pages/api/twilio/index.js file. I also have an pages/api/twilio.js file with the same code snippet just to get it to run. Neither examples worked :( – Randy Nov 17 '21 at 22:23
  • That does look like a correct structure. Next is supposed to treat files in **pages/api** as API endpoints, not "pages", but in your case it thinks it's a page. What version of Next do you use? – tromgy Nov 17 '21 at 22:38
  • "next": "^8.1.0" from package.json. IMO the team before did not intend to use the next api. I'm just trying to get it working again. – Randy Nov 17 '21 at 22:42
  • The current version is 12, I wonder if that API functionality is something that didn't exist 3 years ago in 8.1 – tromgy Nov 17 '21 at 22:51
  • 1
    This appears to be the case. A quick browse through version history on npmjs seems to indicate that API routes were added in version 9.0 – tromgy Nov 17 '21 at 23:03
  • If I upgrade with npm install next@9 will that be incompatible with the apps dependencies? – Randy Nov 17 '21 at 23:26
  • Yes, an upgrade of a major version can potentially break things. It's impossible to tell in advance though. – tromgy Nov 17 '21 at 23:35
  • It's the worst decision but I made a copy of the codebase so i'll find out soon. I'm pretty sure it will break a lot :| – Randy Nov 17 '21 at 23:44

1 Answers1

0

You can read in the comment thread Next@8 was before API routes were added to the framework. I ended up using a workaround where I used the rails backend server. Next version 9+ has api routes where any file in a pages/api directory is treated as a server backend api file. Next 8 was treating pages/api/file as a front-end webpage file looking for react.

Randy
  • 21
  • 3