Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Contentful.js doesn't work with Nuxt3 #1233

Closed
thiagorossener opened this issue Apr 26, 2022 · 27 comments
Closed

Contentful.js doesn't work with Nuxt3 #1233

thiagorossener opened this issue Apr 26, 2022 · 27 comments

Comments

@thiagorossener
Copy link

Expected Behavior

Contentful.js SDK works with Nuxt3 when building for production.

Actual Behavior

When creating a plugin to use Contentful:

import * as contentful from "contentful";

It works fine locally when running npm run dev.

However, when building for production, this happens:

[nuxt] [request error] contentful.createClient is not a function

Steps to Reproduce

  1. Create an entry with a "title" field in Contentful.

  2. Create a project using Nuxt3:
    npx nuxi init nuxt-app
    cd nuxt-app

  3. Install Contentful.js
    npm install contentful -D

  4. Create the file plugins/contentful.js and add:

import * as contentful from "contentful";

export default defineNuxtPlugin((nuxtApp) => {
  const client = contentful.createClient({
    space: "YOUR_SPACE_ID",
    accessToken: "YOUR_ACCESS_TOKEN",
  });

  nuxtApp.provide("contentfulClient", client);
});
  1. Then, in app.vue:
<template>
  <div>
    {{ entry.fields.title }}
  </div>
</template>

<script setup>
  const { $contentfulClient } = useNuxtApp();
  const entry = await $contentfulClient.getEntry("YOUR_ENTRY_ID");
</script>
  1. Run npm run dev and see that the title appears as expected.
  2. Run npm run build, then npm run preview. An error 500 occurs, in the log you see:
    [nuxt] [request error] contentful.createClient is not a function

Context

I'm trying to deploy my application on Netlify.

Environment

  • Language Version: Node v16.14.0
  • Package Manager Version: NPM 8.3.1
  • Browser Version: Version 100.0.4896.127 (Official Build) (x86_64)
  • Operating System: macOS Monterey v12.2.1Darwin *** 21.3.0 Darwin Kernel Version 21.3.0: Wed Jan 5 21:37:58 PST 2022; root:xnu-8019.80.24~20/RELEASE_X86_64 x86_64
  • Package Version: "contentful": "^9.1.25" and "nuxt": "3.0.0-rc.1"
  • Which API are you using?: Trying to use Contentful JavaScript Content Delivery Library
@davidwarrington
Copy link

I've run into the same issue in an Astro project. Interestingly in my case I only have this issue when building the site, not whilst Vite is running in watch mode.

I've played around with the stable and beta version of this package, along with named vs default imports and found this combination to work for me in both dev and production mode:

Install the beta version with

yarn add contentful@beta-v10

Then switch your usage like this

- import { createClient } from 'contentful';
+ import contentful from 'contentful';

- export const client = createClient({...});
+ export const client = contentful.createClient({...});

@denisedelbando
Copy link

What is the difference between the two?

import { createClient as createClientOrig } from 'contentful'; 
import { createClient as createClientToo } from 'contentful-management';

@cody-ta
Copy link

cody-ta commented Aug 14, 2022

contentful@beta-v10

Your solution is not working.

In short, this is a problem when using contenful.js with Vite.

@fmarcheski
Copy link

I had this same issue. Worked in Dev, but not in Production.
The below code solved my problem. Basically, in Production you must use contentful.createClient. In Dev you can use createClient.

Hope this helps someone else.

import { createClient } from "contentful";
import contentful from 'contentful'

export default defineNuxtPlugin((nuxtApp) => {
  const config = useRuntimeConfig();

  const createClientFunc = process.env.NODE_ENV === 'development' ? createClient : contentful.createClient

  const client = createClientFunc({
    space: config.CTF_SPACE_ID,
    accessToken: config.CTF_CDA_ACCESS_TOKEN,
  });

  return {
    provide: {
      contentfulClient: client,
    },
  };
});

@thiagorossener
Copy link
Author

Thanks @fmarcheski! I had to do the same thing, ended up forgetting to post it here. That solution works for me too.

@JackEdwardLyons
Copy link

Any updates on a fix for this? I've tried the suggestions above, but no success.
Running on "contentful": "^10.0.0-beta-v10.8" and "nuxt": "npm:nuxt3@latest".
Getting either this error Named export 'createClient' not found. or the error from the OP.

@marcolink
Copy link
Member

Hi @JackEdwardLyons,
Sorry to hear you're still running into this issue! Unfortunately, I have personally no experience with nuxt.
I have tried to create a very basic example to understand what is going on- maybe you want to have a look?

As far as I can see the import is working fine - the only error I see is expected (no space id and credentials provided, therefore also no entries returned)

https://codesandbox.io/s/condescending-nightingale-bkvx51

@JackEdwardLyons
Copy link

JackEdwardLyons commented Nov 1, 2022

Hi @marcolink thanks for the quick response. I appreciate it.
I had a look at your codesandbox link and it is using "nuxt": "^2.15.0".

I forked it and bumped the version to the latest RC release, and now it's not loading correctly. If you open the terminal and run yarn build you'll get this error 'default' is not exported by plugins/contentful.js, imported by virtual:nuxt:/sandbox/.nuxt/plugins/client.mjs

Please take a look:

https://codesandbox.io/s/small-breeze-5fnx3x

Note: I've tested from nuxt 3 rc.0 onward and this error occurs. It does not occur on nuxt 2.15.8. From what I've read in other GH issues, this could be vite related. I'm not exactly sure if there is some vite specific config required, but just wondering, do you have any knowledge of vite and it's interaction with contentful?

@marcolink
Copy link
Member

@JackEdwardLyons
Changed the export/import of the plugin to use defaults, but now I get a different error

https://codesandbox.io/s/great-dust-v0oqz8

 ERROR  Nitro is not initialized yet. You can call useNitro() only after ready hook.             

Not sure what it means?

@JackEdwardLyons
Copy link

JackEdwardLyons commented Nov 1, 2022

Hi @marcolink thanks again, I checked your fork, and set the nuxt verion to the latest RC. I've updated the plugin code and been able to run a build - it's not a full reproduction of the issue I am facing, but at least running yarn build and yarn start seems to work (add your own credentials to see the screen actually show content).

https://codesandbox.io/s/stoic-cherry-9jl09s?file=/plugins/contentful.js

And just for reference here is the full error from my actual app:

[worker reload] [worker init] Named export 'createClient' not found. The requested module 'app/node_modules/contentful/dist/contentful.node.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:

import pkg from 'app/node_modules/contentful/dist/contentful.node.js';
const { createClient } = pkg;


  import { createClient } from 'node_modules/contentful/dist/contentful.node.js';
  ^^^^^^^^^^^^
  SyntaxError: Named export 'createClient' not found. The requested module 'node_modules/contentful/dist/contentful.node.js' is a CommonJS module, which may not support all module.exports as named exports.
  CommonJS modules can always be imported via the default export, for example using:
  
  import pkg from 'node_modules/contentful/dist/contentful.node.js';
  const { createClient } = pkg;
  
  at ModuleJob._instantiate (node:internal/modules/esm/module_job:128:21)
  at async ModuleJob.run (node:internal/modules/esm/module_job:194:5)
  at async Promise.all (index 0)
  at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
  at async loadESM (node:internal/process/esm_loader:88:5)
  at async handleMainPromise (node:internal/modules/run_main:61:12)

ℹ Vite client warmed up in 12777ms  

@JackEdwardLyons
Copy link

Hey @marcolink just want to say thanks for the help and that it's likely a Nuxt/Vite issue or something else on my side. I don't think you need to look into this any more.

@ruriarte-zaelot
Copy link

Hey @marcolink just want to say thanks for the help and that it's likely a Nuxt/Vite issue or something else on my side. I don't think you need to look into this any more.

Hey Jack have you found a way to solve this, I am really not getting it to work, I am getting the same error messages.

@marcolink
Copy link
Member

@ruriarte-zaelot what version of contentful.js are you using?

@ruriarte-zaelot
Copy link

@ruriarte-zaelot what version of contentful.js are you using?

Hey marco thanks for your quick response. I'm using version 9.2.17

@marcolink
Copy link
Member

Ok, that version introduces a fix for ESM builds.
I'm completely unexperienced with VUE and NUXT, but does this work:
https://codesandbox.io/p/sandbox/nuxt-with-contentful-m1bwfp

@ruriarte-zaelot
Copy link

@marcolink The problem I'm facing is that the way you imported in the sandbox is working for me but only in local. Same problem @thiagorossener was having. When I deploy to dev/production it throws this error.

Named export 'createClient' not found. The requested module 'contentful' is a CommonJS module, which may not support all module.exports as named exports.

CommonJS modules can always be imported via the default export, for example using:

import pkg from 'contentful';

const { createClient } = pkg;

What worked best for me so far was to use the procedure suggested by @fmarcheski . That is working but only for v10beta, not for v9.

@adi-kumar
Copy link

I am also having this issue in my current application using nuxt:3.0.0 and contentful:9.2.17.
@ruriarte-zaelot To confirm, were you able to resolve the error you mentioned by switching to the v10beta release? What version of nuxt were you using?

@ruriarte-zaelot
Copy link

@adi-kumar using nuxt 3.0.0 with contentful v10beta applying the procedure given by @fmarcheski works.

@eriklindgren
Copy link

You don't need to switch to the beta version of contentful to fix this. The beta version seems to have some issues (it didn't respect the include setting on my calls when I tried it for example). In the built server, the createClient function ends up on the contentful.default object instead of the contentful object. I'm sure there's an explanation, probably something to do with interoperability between CommonJS and ES Modules.

Anyway, I solved it like this:

import * as contentful from 'contentful'

const client = contentful.createClient
    ? contentful.createClient({...})
    : contentful.default.createClient({...})

I'm using nuxt 3.2.3 and contentful 9.3.3.

@SatoshiRoppongi
Copy link

Cannot find contentful.default..

@eriklindgren
Copy link

Cannot find contentful.default..

The solution still works for me on nuxt 3.3.1 and contentful 9.3.5. I build the app with nuxi build and then run it with node .output/server/index.mjs. In the server/shell, the contentful.default object has the createClient function and in the client/browser the createClient function is on the contentful object itself.

If I run the app with nuxi dev, the createClient function is on the contentful object in both server and client 🤷

@rutgerbakker95
Copy link

Cannot find contentful.default..

I had to ignore this with /* eslint-disable import/namespace */. The solution from @eriklindgren is working for me.

  • Operating System: Darwin
  • Node Version: v18.14.1
  • Nuxt Version: 3.3.1
  • Nitro Version: 2.3.1
  • Builder: vite
  • User Config: target, ssr, experimental, runtimeConfig, build, tailwindcss, vite, css, image, modules, i18n

@lisaschumann
Copy link

For me, @fmarcheski solution worked like a charm! Thank you.

@peeyushsingla
Copy link

I am importing with import * as contentful from 'contentful'; and observed the structure of contentful object differs when running dev server vs build

dev server

{
  contentful: Object [Module] {
    createClient: [Getter],
    createGlobalOptions: [Getter]
  }
}

build

{
  contentful: [Module: null prototype] {
    contentful: undefined,
    default: Object [Module] {
      createClient: [Getter],
      createGlobalOptions: [Getter]
    }
  }
}

@danemauland
Copy link
Contributor

danemauland commented Sep 25, 2023

This is a known issue when using Vite for server side rendering a CommonJS module, but it sounds like they're looking into fixing it for Vite 5. This issue thread has more information. One more potential fix would be to import contentful this way:

import contentful from 'contentful/dist/contentful.node.min.js';

But then you'll also want to polyfill global in your index.html file:

<script type="application/javascript">
  if (global === undefined) {
    var global = window;
  }
</script>

@marcolink
Copy link
Member

closing this for now

@larsdouweschuitema
Copy link

It seems they stated it as fixed on the vite issue. However, I am experiencing the exact same issue on the latest version of contentful using the following nuxt and vite versions:

"contentful": "^10.9.3",
"nuxt": "^3.11.2",
"vite": "5.2.11"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests