deepgram-js-sdk icon indicating copy to clipboard operation
deepgram-js-sdk copied to clipboard

ReferenceError: Cannot access 'isBrowser' before initialization

Open clacladev opened this issue 1 year ago • 11 comments

What is the current behavior?

I am trying to use the JS sdk in a Next.js 15 App Router api route. So executed on the server.

I am instantiating Deepgram as per instructions here with

const deepgram = createClient(process.env.DEEPGRAM_API_KEY);

but I get the following error:

⨯ ReferenceError: Cannot access 'isBrowser' before initialization
    at Module.isBrowser
    ...
  page: '/api/audio/text-to-speech'
}
 POST /api/audio/text-to-speech 500 in 50ms

Steps to reproduce

  • Create a Next.js 15 App router codebase
  • create an api route
  • in the same file add const deepgram = createClient(process.env.DEEPGRAM_API_KEY);
  • call the route
  • error will be thrown in the app console

Expected behavior

To just be able to use the sdk in an api route

Please tell us about your environment

We want to make sure the problem isn't specific to your operating system or programming language.

  • Operating System/Version: macOS
  • Language: TypeScript
  • Browser: Chrome
  • Next.js: 15.0.1
  • @deepgram/sdk: 3.9.0

Other information

This is the stack trace:

⨯ ReferenceError: Cannot access 'isBrowser' before initialization
    at Module.isBrowser (/Users/claudio/Dev/web/cuecard/.next/server/chunks/node_modules_@deepgram_sdk_dist_module_6533bc._.js:147:23)
    at [project]/node_modules/@deepgram/sdk/dist/module/lib/constants.js [app-route] (ecmascript) (/Users/claudio/Dev/web/cuecard/.next/server/chunks/node_modules_@deepgram_sdk_dist_module_6533bc._.js:99:211)
    at instantiateModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:644:12)
    at esmImport (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:132:20)
    at [project]/node_modules/@deepgram/sdk/dist/module/lib/helpers.js [app-route] (ecmascript) (/Users/claudio/Dev/web/cuecard/.next/server/chunks/node_modules_@deepgram_sdk_dist_module_6533bc._.js:160:177)
    at instantiateModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:644:12)
    at esmImport (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:132:20)
    at [project]/node_modules/@deepgram/sdk/dist/module/packages/ListenRestClient.js [app-route] (ecmascript) (/Users/claudio/Dev/web/cuecard/.next/server/chunks/node_modules_@deepgram_sdk_dist_module_6533bc._.js:676:175)
    at instantiateModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:644:12)
    at esmImport (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:132:20)
    at [project]/node_modules/@deepgram/sdk/dist/module/packages/ListenClient.js [app-route] (ecmascript) (/Users/claudio/Dev/web/cuecard/.next/server/chunks/node_modules_@deepgram_sdk_dist_module_6533bc._.js:1269:189)
    at instantiateModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:644:12)
    at esmImport (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:132:20)
    at [project]/node_modules/@deepgram/sdk/dist/module/DeepgramClient.js [app-route] (ecmascript) (/Users/claudio/Dev/web/cuecard/.next/server/chunks/node_modules_@deepgram_sdk_dist_module_6533bc._.js:2909:185)
    at instantiateModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:644:12)
    at esmImport (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:132:20)
    at [project]/node_modules/@deepgram/sdk/dist/module/index.js [app-route] (ecmascript) <locals> (/Users/claudio/Dev/web/cuecard/.next/server/chunks/node_modules_@deepgram_sdk_dist_module_6533bc._.js:3030:175)
    at instantiateModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:644:12)
    at esmImport (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:132:20)
    at [project]/libs/deepgram/speech.ts [app-route] (ecmascript) (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[root of the server]__c97bc6._.js:107:182)
    at instantiateModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:644:12)
    at esmImport (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:132:20)
    at [project]/app/api/audio/text-to-speech/route.ts [app-route] (ecmascript) (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[root of the server]__c97bc6._.js:490:132)
    at instantiateModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:589:23)
    at getOrInstantiateModuleFromParent (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:644:12)
    at esmImport (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:132:20)
    at [project]/node_modules/next/dist/esm/build/templates/app-route.js { INNER_APP_ROUTE => "[project]/app/api/audio/text-to-speech/route.ts [app-route] (ecmascript)" } [app-route] (ecmascript) (/Users/claudio/Dev/web/cuecard/.next/server/chunks/_5829b8._.js:47:158)
    at instantiateModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:589:23)
    at instantiateRuntimeModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:652:12)
    at Object.getOrInstantiateRuntimeModule (/Users/claudio/Dev/web/cuecard/.next/server/chunks/[turbopack]_runtime.js:668:12)
    at Object.<anonymous> (/Users/claudio/Dev/web/cuecard/.next/server/app/api/audio/text-to-speech/route.js:13:26)
    at Module._compile (node:internal/modules/cjs/loader:1469:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1548:10)
    at Module.load (node:internal/modules/cjs/loader:1288:32)
    at Module._load (node:internal/modules/cjs/loader:1104:12)
    at Module.require (node:internal/modules/cjs/loader:1311:19)
    at mod.require (/Users/claudio/Dev/web/cuecard/node_modules/next/dist/server/require-hook.js:65:28)
    at require (node:internal/modules/helpers:179:18)
    at requirePage (/Users/claudio/Dev/web/cuecard/node_modules/next/dist/server/require.js:103:84)
    at loadComponentsImpl (/Users/claudio/Dev/web/cuecard/node_modules/next/dist/server/load-components.js:99:57)
    at async DevServer.findPageComponentsImpl (/Users/claudio/Dev/web/cuecard/node_modules/next/dist/server/next-server.js:732:36)
    at async DevServer.findPageComponents (/Users/claudio/Dev/web/cuecard/node_modules/next/dist/server/dev/next-dev-server.js:611:20)
    at async DevServer.renderPageComponent (/Users/claudio/Dev/web/cuecard/node_modules/next/dist/server/base-server.js:2279:24) {
  page: '/api/audio/text-to-speech'
}
 POST /api/audio/text-to-speech 500 in 50ms

clacladev avatar Oct 29 '24 11:10 clacladev

Having the same issue using Next 15.1.2

VGraupera avatar Dec 24 '24 18:12 VGraupera

The SDK remains untested and (it looks) incompatible with some new features of Next.js 15. For now, you can downgrade to Next.js 14, or you can connect to Deepgram via a pages/api express-like proxy instead of using the SDK in Next.js specifically

lukeocodes avatar Dec 30 '24 15:12 lukeocodes

thanks, how do you "connect to Deepgram via a pages/api express-like proxy instead of using the SDK in Next.js specifically" ? is there an example of that?

VGraupera avatar Dec 30 '24 21:12 VGraupera

Following this. I have, for now, delegated the work to a Python lambda and called the lambda within my Next API route. Alternatively, one may call the backend API directly (cURL). I believe it is also related to webpack, see https://github.com/webpack/webpack/issues/12724.

To confirm, could you share your Next config file and tsconfig files?

I'm also experiencing the same issue, here are mine:

// next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
  reactStrictMode: true,
  eslint: {
    ignoreDuringBuilds: true,
  },
  typescript: {
    ignoreBuildErrors: true,
  },
  images: {
    remotePatterns: [
      {
        hostname: "https://s3.eu-central-1.amazonaws.com",
      },
      {
        hostname: "localhost",
      },
    ],
  },
};

const withPWA = require("next-pwa")({
  dest: "/public",
  scope: "/src/app",
  disable: process.env.VERCEL_ENV == "development",
  register: true,
  skipWaiting: true,
});

module.exports = withPWA(nextConfig);

And

// tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "lib": ["dom", "dom.iterable", "esnext"],
    "allowJs": true,
    "skipLibCheck": true,
    "strict": true,
    "noEmit": true,
    "esModuleInterop": true,
    "module": "esnext",
    "moduleResolution": "bundler",
    "resolveJsonModule": true,
    "isolatedModules": true,
    "jsx": "preserve",
    "incremental": true,
    "plugins": [
      {
        "name": "next"
      }
    ],
    "paths": {
      "@/*": ["./src/*"]
    }
  },
  "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
  "exclude": ["node_modules"]
}

nicolello-dev avatar Jan 03 '25 06:01 nicolello-dev

Any updates on this?

Pablo4Coding avatar Jan 20 '25 13:01 Pablo4Coding

Any updates on this?

As they replied in related issue, current SDK is not compatible with Next.js 15 and offer to downgrade

malakhov-dmitrii avatar Jan 21 '25 13:01 malakhov-dmitrii

This is very disappointing. :(

VGraupera avatar Feb 12 '25 17:02 VGraupera

same issue, here is a workaround

do not use import { createClient } from '@deepgram/sdk'

use this instead

import { createRequire } from 'node:module'
const require = createRequire(import.meta.url)
const { createClient } = require('@deepgram/sdk')

lovetingyuan avatar Feb 23 '25 13:02 lovetingyuan

same issue, here is a workaround

do not use import { createClient } from '@deepgram/sdk'

use this instead

import { createRequire } from 'node:module' const require = createRequire(import.meta.url) const { createClient } = require('@deepgram/sdk')

This one works nicely for me, thanks @lovetingyuan 💪

yhauxell avatar Mar 04 '25 21:03 yhauxell

i tried this workaround. Got the following

` ⨯ ./context/Deepgram.jsx Code generation for chunk item errored An error occurred while generating the chunk item [project]/context/Deepgram.jsx [app-client] (ecmascript)

Caused by:

  • the chunking context (unknown) does not support external modules (request: node:module)

Debug info:

  • An error occurred while generating the chunk item [project]/context/Deepgram.jsx [app-client] (ecmascript)
  • Execution of <ModuleChunkItem as EcmascriptChunkItem>::content_with_async_module_info failed
  • Execution of EcmascriptModuleContent::new failed
  • the chunking context (unknown) does not support external modules (request: node:module) `

VGraupera avatar Mar 27 '25 20:03 VGraupera

Hello I just had to use the Deepgram API directly, thankfully, the deepgram feature that I am needing, is not too complex to do just sending an http request. Hope this workaround help someone:

const transcribeRecordingUrl = async ({
  recordingUrl: url,
}: {
  recordingUrl: string;
}) => {
  // Define the request headers object
  const headers = {
    Accept: "application/json",
    Authorization: `Token ${process.env.DEEPGRAM_API_KEY}`,
    "Content-Type": "application/json",
  };

  // Make the POST request using fetch API
  const response = await fetch(
    "https://api.deepgram.com/v1/listen?smart_format=true&model=nova-3",
    {
      method: "POST",
      headers: headers, // Pass the headers object
      body: JSON.stringify({ url, smart_format: true }), // Convert data object to JSON string
    }
  );

  const { results }: SyncPrerecordedResponse = await response.json(); // Parse the JSON response

  const transcription = results.channels.reduce(
    (allChannelsData, { alternatives }) => {
      return (
        allChannelsData +
        alternatives.reduce(
          (allAlternativesData, { transcript }) =>
            allAlternativesData + transcript,
          ""
        )
      );
    },
    ""
  );
  return transcription;
};

export default transcribeRecordingUrl;

eduardoChapters avatar Mar 31 '25 19:03 eduardoChapters