adobe / react-spectrum

A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences.
https://react-spectrum.adobe.com
Apache License 2.0
13.02k stars 1.13k forks source link

How to use React Spectrum with Next.js #760

Closed vestimir closed 4 years ago

vestimir commented 4 years ago

❔ Question

Next.js does not support importing of CSS from node_modules, is there a workaround for getting Spectrum and Next.js to play together?

🔦 Context

I just created an empty Next.js project and tried to import @adobe/react-spectrum but it complains with the following error:

error - ./node_modules/@react-aria/visually-hidden/dist/main.css
Global CSS cannot be imported from within node_modules.
Read more: https://err.sh/next.js/css-npm
Location: node_modules/@react-aria/visually-hidden/dist/module.js

💻 Code Sample

Empty Next.js project with the example from Spectrum Getting started in pages/index.js

devongovett commented 4 years ago

Hmm, I think you may need to override the webpack config to add css-loader? Possibly the next-css package could help? https://github.com/vercel/next-plugins/tree/master/packages/next-css

ross-pfahler commented 4 years ago

I believe this is because of this https://github.com/vercel/next.js/issues/12079. It does seem like the vercel team is working on it.

mrmntte commented 4 years ago

Could you allow us to import the css manually? In Next.js, importing global css is allowed only from _app.js

RafalFilipek commented 4 years ago

This should be solved in near future (hopefully). https://github.com/vercel/next.js/discussions/15208

devongovett commented 4 years ago

835 sets up a test harness to ensure all the components work in an SSR environment. If anyone would like to contribute tests to help with this effort, please feel free! 😄

krijoh92 commented 4 years ago

Not sure this is a good workaround or not, but it is a workaround. Install the following dependencies:

And edit your next.config.js to look something like this:

const withPlugins = require('next-compose-plugins')
const withCSS = require('@zeit/next-css')
const withTM = require('next-transpile-modules')([
  // Not sure all of the following need to be included, just did to make sure
  '@adobe/react-spectrum',
  '@adobe/react-spectrum-ui',
  '@react-aria',
  '@react-spectrum',
  '@react-stately',
])

if (typeof require !== 'undefined') {
  require.extensions['.less'] = () => {}
  require.extensions['.css'] = (file) => {}
}
global.requestAnimationFrame = (cb) => cb()

module.exports = withPlugins([withCSS, withTM], {
  // Your next configuration
})
devongovett commented 4 years ago

This should be fixed as of #994! We have a bit of testing to do, but things are looking good. We'll be getting this into the next release along with some docs about how to use React Spectrum/React Aria with Next.js and SSR in general. 😄

jcarrera commented 4 years ago

@devongovett awesome!

SheaBelsky commented 4 years ago

@devongovett Thank you for resolving this issue, Devon! Is there an estimated timeline for when the next release of React Spectrum is going to be? We're considering moving away from a different design library, and I'd love to see if Spectrum/Aria/Stately meet our use cases going forward (in a Next.js application.)

devongovett commented 4 years ago

@SheaBelsky we have testing scheduled for Friday, so should be early next week if all goes well. Working on the docs as well. 😄

SheaBelsky commented 4 years ago

@devongovett That's great to hear, thank you!

devongovett commented 4 years ago

Release is now out! See our guides for React Spectrum and React Aria to learn more. 🎉

snax4a commented 2 years ago

Hi, I am seeing similar issue with @adobe/react-spectrum": "^3.21.2" and next 12.2.5 I am using pnpm package manager. I am trying to use Picker component.

Error:

./node_modules/.pnpm/@react-spectrum+actiongroup@3.6.1_vq3pvykbfgerr5rtx4n53bcbxy/node_modules/@react-spectrum/actiongroup/dist/main.css
Global CSS cannot be imported from within node_modules.
Read more: https://nextjs.org/docs/messages/css-npm
Location: node_modules/.pnpm/@react-spectrum+actiongroup@3.6.1_vq3pvykbfgerr5rtx4n53bcbxy/node_modules/@react-spectrum/actiongroup/dist/module.js

next info output:

    Operating System:
      Platform: darwin
      Arch: x64
      Version: Darwin Kernel Version 21.6.0: Mon Aug 22 20:17:10 PDT 2022; root:xnu-8020.140.49~2/RELEASE_X86_64
    Binaries:
      Node: 16.15.1
      npm: 8.11.0
      Yarn: 1.22.17
      pnpm: 7.11.0
    Relevant packages:
      next: 12.2.5
      eslint-config-next: 12.2.5
      react: 18.2.0
      react-dom: 18.2.0
giovanniincammicia commented 2 years ago

I've followed the instructions here: https://react-spectrum.adobe.com/react-spectrum/ssr.html

It still doesn't work on Next.js. I'm trying to use @react-spectrum/datepicker It's been 2 years, can we have a feedback or a guide on how to fix it?

reidbarber commented 2 years ago

@GiovanniIncammicia It should be working now. Can you post any specific errors you're getting? Don't forget to disable React strict mode if it is enabled in next.config.js.

tknoq commented 2 years ago

I'm having a similar issue with the latest version of Next.js and react-spectrum "^3.22.0". Unfortunately, this problem seems to have reoccurred. The cause is probably on the Next.js side, but I hope it will be fixed anyway.

snax4a commented 2 years ago

@reidbarber I'm still not able to get this working with next.js.

next info output:

    Operating System:
      Platform: darwin
      Arch: x64
      Version: Darwin Kernel Version 21.6.0: Mon Aug 22 20:17:10 PDT 2022; root:xnu-8020.140.49~2/RELEASE_X86_64
    Binaries:
      Node: 16.15.1
      npm: 8.11.0
      Yarn: 1.22.19
      pnpm: 7.13.5
    Relevant packages:
      next: 12.3.1
      eslint-config-next: 12.3.1
      react: 18.2.0
      react-dom: 18.2.0

This is my next.config.mjs

// @ts-check

import withTM from 'next-transpile-modules';

/**
 * Don't be scared of the generics here.
 * All they do is to give us autocompletion when using this.
 *
 * @template {import('next').NextConfig} T
 * @param {T} config - A generic parameter that flows through to the return type
 * @constraint {{import('next').NextConfig}}
 */
function defineNextConfig(config) {
  return config;
}

export default withTM([
  '@adobe/react-spectrum',
  '@react-spectrum/actiongroup',
  '@react-spectrum/breadcrumbs',
  '@react-spectrum/button',
  '@react-spectrum/badge',
  '@react-spectrum/buttongroup',
  '@react-spectrum/calendar',
  '@react-spectrum/checkbox',
  '@react-spectrum/combobox',
  '@react-spectrum/contextualhelp',
  '@react-spectrum/datepicker',
  '@react-spectrum/dialog',
  '@react-spectrum/divider',
  '@react-spectrum/form',
  '@react-spectrum/icon',
  '@react-spectrum/illustratedmessage',
  '@react-spectrum/image',
  '@react-spectrum/label',
  '@react-spectrum/layout',
  '@react-spectrum/link',
  '@react-spectrum/list',
  '@react-spectrum/listbox',
  '@react-spectrum/menu',
  '@react-spectrum/meter',
  '@react-spectrum/numberfield',
  '@react-spectrum/overlays',
  '@react-spectrum/picker',
  '@react-spectrum/progress',
  '@react-spectrum/provider',
  '@react-spectrum/radio',
  '@react-spectrum/slider',
  '@react-spectrum/searchfield',
  '@react-spectrum/statuslight',
  '@react-spectrum/switch',
  '@react-spectrum/table',
  '@react-spectrum/tabs',
  '@react-spectrum/text',
  '@react-spectrum/textfield',
  '@react-spectrum/theme-dark',
  '@react-spectrum/theme-default',
  '@react-spectrum/theme-light',
  '@react-spectrum/tooltip',
  '@react-spectrum/view',
  '@react-spectrum/well',
  '@spectrum-icons/illustrations',
  '@spectrum-icons/ui',
  '@spectrum-icons/workflow',
])(
  defineNextConfig({
    reactStrictMode: false,
    swcMinify: true,
    output: 'standalone',
    experimental: {
      newNextLinkBehavior: true,
    },
  })
);

I tried with reactStrictMode enabled and disabled option.

I am using pnpm as a package manager. I Installed only "@adobe/react-spectrum": "3.22.0" package

When trying to start dev server I am getting following error:

Failed to load next.config.mjs, see more info here https://nextjs.org/docs/messages/next-config-error
Error: next-transpile-modules - an unexpected error happened when trying to resolve "@react-spectrum/actiongroup". Are you sure the name of the module you are trying to transpile is correct, and it has a package.json with a "main" or an "exports" field?
Error: Can't resolve '@react-spectrum/actiongroup/package.json' in '/Users/szymon/projects/test'
    at getPackageRootDirectory (/Users/szymon/projects/test/node_modules/.pnpm/next-transpile-modules@9.1.0/node_modules/next-transpile-modules/src/next-transpile-modules.js:123:15)
    at Array.map (<anonymous>)
    at withTM (/Users/szymon/projects/test/node_modules/.pnpm/next-transpile-modules@9.1.0/node_modules/next-transpile-modules/src/next-transpile-modules.js:132:34)
    at file:///Users/szymon/projects/test/next.config.mjs:22:3
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
    at async importModuleDynamicallyWrapper (node:internal/vm/module:437:15)
    at async Object.loadConfig [as default] (/Users/szymon/projects/test/node_modules/.pnpm/next@12.3.1_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/server/config.js:68:36)
    at async NextServer.prepare (/Users/szymon/projects/test/node_modules/.pnpm/next@12.3.1_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/server/next.js:127:24)

Also I don't need any react-spectrum styles I just want to use your Picker and Combobox components because of their great onLoadMore prop. I can style it on my own. I could not find that load more feature in any other react combobox / select components.

Can you somehow let us youse your Picker component without any styles if there are such problems in next.js?

Unfortunatelly react-aria/useSelect and react-aria/useComboBox hooks don't have onLoadMore feature. If they did that would be awesome.

snax4a commented 2 years ago

@reidbarber I'm still not able to get this working with next.js.

next info output:

    Operating System:
      Platform: darwin
      Arch: x64
      Version: Darwin Kernel Version 21.6.0: Mon Aug 22 20:17:10 PDT 2022; root:xnu-8020.140.49~2/RELEASE_X86_64
    Binaries:
      Node: 16.15.1
      npm: 8.11.0
      Yarn: 1.22.19
      pnpm: 7.13.5
    Relevant packages:
      next: 12.3.1
      eslint-config-next: 12.3.1
      react: 18.2.0
      react-dom: 18.2.0

This is my next.config.mjs

// @ts-check

import withTM from 'next-transpile-modules';

/**
 * Don't be scared of the generics here.
 * All they do is to give us autocompletion when using this.
 *
 * @template {import('next').NextConfig} T
 * @param {T} config - A generic parameter that flows through to the return type
 * @constraint {{import('next').NextConfig}}
 */
function defineNextConfig(config) {
  return config;
}

export default withTM([
  '@adobe/react-spectrum',
  '@react-spectrum/actiongroup',
  '@react-spectrum/breadcrumbs',
  '@react-spectrum/button',
  '@react-spectrum/badge',
  '@react-spectrum/buttongroup',
  '@react-spectrum/calendar',
  '@react-spectrum/checkbox',
  '@react-spectrum/combobox',
  '@react-spectrum/contextualhelp',
  '@react-spectrum/datepicker',
  '@react-spectrum/dialog',
  '@react-spectrum/divider',
  '@react-spectrum/form',
  '@react-spectrum/icon',
  '@react-spectrum/illustratedmessage',
  '@react-spectrum/image',
  '@react-spectrum/label',
  '@react-spectrum/layout',
  '@react-spectrum/link',
  '@react-spectrum/list',
  '@react-spectrum/listbox',
  '@react-spectrum/menu',
  '@react-spectrum/meter',
  '@react-spectrum/numberfield',
  '@react-spectrum/overlays',
  '@react-spectrum/picker',
  '@react-spectrum/progress',
  '@react-spectrum/provider',
  '@react-spectrum/radio',
  '@react-spectrum/slider',
  '@react-spectrum/searchfield',
  '@react-spectrum/statuslight',
  '@react-spectrum/switch',
  '@react-spectrum/table',
  '@react-spectrum/tabs',
  '@react-spectrum/text',
  '@react-spectrum/textfield',
  '@react-spectrum/theme-dark',
  '@react-spectrum/theme-default',
  '@react-spectrum/theme-light',
  '@react-spectrum/tooltip',
  '@react-spectrum/view',
  '@react-spectrum/well',
  '@spectrum-icons/illustrations',
  '@spectrum-icons/ui',
  '@spectrum-icons/workflow',
])(
  defineNextConfig({
    reactStrictMode: false,
    swcMinify: true,
    output: 'standalone',
    experimental: {
      newNextLinkBehavior: true,
    },
  })
);

I tried with reactStrictMode enabled and disabled option.

I am using pnpm as a package manager. I Installed only "@adobe/react-spectrum": "3.22.0" package

When trying to start dev server I am getting following error:

Failed to load next.config.mjs, see more info here https://nextjs.org/docs/messages/next-config-error
Error: next-transpile-modules - an unexpected error happened when trying to resolve "@react-spectrum/actiongroup". Are you sure the name of the module you are trying to transpile is correct, and it has a package.json with a "main" or an "exports" field?
Error: Can't resolve '@react-spectrum/actiongroup/package.json' in '/Users/szymon/projects/test'
    at getPackageRootDirectory (/Users/szymon/projects/test/node_modules/.pnpm/next-transpile-modules@9.1.0/node_modules/next-transpile-modules/src/next-transpile-modules.js:123:15)
    at Array.map (<anonymous>)
    at withTM (/Users/szymon/projects/test/node_modules/.pnpm/next-transpile-modules@9.1.0/node_modules/next-transpile-modules/src/next-transpile-modules.js:132:34)
    at file:///Users/szymon/projects/test/next.config.mjs:22:3
    at ModuleJob.run (node:internal/modules/esm/module_job:198:25)
    at async Promise.all (index 0)
    at async ESMLoader.import (node:internal/modules/esm/loader:385:24)
    at async importModuleDynamicallyWrapper (node:internal/vm/module:437:15)
    at async Object.loadConfig [as default] (/Users/szymon/projects/test/node_modules/.pnpm/next@12.3.1_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/server/config.js:68:36)
    at async NextServer.prepare (/Users/szymon/projects/test/node_modules/.pnpm/next@12.3.1_biqbaboplfbrettd7655fr4n2y/node_modules/next/dist/server/next.js:127:24)

Also I don't need any react-spectrum styles I just want to use your Picker and Combobox components because of their great onLoadMore prop. I can style it on my own. I could not find that load more feature in any other react combobox / select components.

Can you somehow let us youse your Picker component without any styles if there are such problems in next.js?

Unfortunatelly react-aria/useSelect and react-aria/useComboBox hooks don't have onLoadMore feature. If they did that would be awesome.

I managed to get this working by switching to yarn. For some reason it is not working with pnpm 🤔

snowystinger commented 2 years ago

Looks like you used next.config.mjs, which uses ESM. See https://github.com/adobe/react-spectrum/pull/3630 we're working on support for that. If you used next.config.js and edited the internals to be require's, it should work.

snax4a commented 2 years ago

Looks like you used next.config.mjs, which uses ESM. See #3630 we're working on support for that. If you used next.config.js and edited the internals to be require's, it should work.

ESM is not a problem here, I tried with .config.js and requires and there is the same error when using pnpm.

It looks like there is some issue with peer dependencies. I installed only "@adobe/react-spectrum": "3.22.0" I am not importing any component, i only wrapped my app with ssr and theme providers:

<SSRProvider>
    <Provider theme={defaultTheme} colorScheme='light'>
        ....
    </Provider>
</SSRProvider>

When i remove node_modules and install dependencies with yarn and then start dev server i get this error:

Error: next-transpile-modules - an unexpected error happened when trying to resolve "@spectrum-icons/illustrations". Are you sure the name of the module you are trying to transpile is correct, and it has a package.json with a "main" or an "exports" field?

So I installed this package @spectrum-icons/illustrations and it now worked

I will post here both lock files maybe it will be helpfull

First one isyarn.lock (react spectrum is working): https://gist.github.com/snax4a/76b166f467071a5f83d5c80729e38817

The second one is pnpm-lock.yaml (react spectrum not working, error resolving @react-spectrum/actiongroup package - full error was posted above): https://gist.github.com/snax4a/3baa88ce306afefcb4f52cb1d8374abe

matijagrcic commented 1 year ago

The https://react-spectrum.adobe.com/react-spectrum/ssr.html#nextjs is outdated. In Next v13.1 you can do the following

-const withTM = require('next-transpile-modules')(['awesome_module']);

-module.exports = withTM({});
+module.exports = {
+  transpilePackages: ['awesome_module'],
+};

Ref: https://github.com/martpie/next-transpile-modules/releases/tag/the-end

So your next.config.js should look like the below

module.exports = {
  transpilePackages: [
    "@adobe/react-spectrum",
    "@react-spectrum/actiongroup",
    "@react-spectrum/badge",
    "@react-spectrum/breadcrumbs",
    "@react-spectrum/button",
    "@react-spectrum/buttongroup",
    "@react-spectrum/calendar",
    "@react-spectrum/checkbox",
    "@react-spectrum/color",
    "@react-spectrum/combobox",
    "@react-spectrum/contextualhelp",
    "@react-spectrum/datepicker",
    "@react-spectrum/dialog",
    "@react-spectrum/divider",
    "@react-spectrum/dnd",
    "@react-spectrum/form",
    "@react-spectrum/icon",
    "@react-spectrum/illustratedmessage",
    "@react-spectrum/image",
    "@react-spectrum/label",
    "@react-spectrum/labeledvalue",
    "@react-spectrum/layout",
    "@react-spectrum/link",
    "@react-spectrum/list",
    "@react-spectrum/listbox",
    "@react-spectrum/menu",
    "@react-spectrum/meter",
    "@react-spectrum/numberfield",
    "@react-spectrum/overlays",
    "@react-spectrum/picker",
    "@react-spectrum/progress",
    "@react-spectrum/provider",
    "@react-spectrum/radio",
    "@react-spectrum/slider",
    "@react-spectrum/searchfield",
    "@react-spectrum/statuslight",
    "@react-spectrum/switch",
    "@react-spectrum/table",
    "@react-spectrum/tabs",
    "@react-spectrum/text",
    "@react-spectrum/textfield",
    "@react-spectrum/theme-dark",
    "@react-spectrum/theme-default",
    "@react-spectrum/theme-light",
    "@react-spectrum/tooltip",
    "@react-spectrum/view",
    "@react-spectrum/well",
    "@spectrum-icons/illustrations",
    "@spectrum-icons/ui",
    "@spectrum-icons/workflow",
  ],

Ref: next.config.js and https://github.com/adobe/react-spectrum/issues/3895

snowystinger commented 1 year ago

Thanks for the update, docs update here https://github.com/adobe/react-spectrum/pull/3897

ktsnkmrcom commented 1 year ago

I think you already know...

Add @react-spectrum/actionbar

module.exports = { transpilePackages: [ '@adobe/react-spectrum', '@react-spectrum/actionbar', <<< '@react-spectrum/actiongroup',

best regards.