sentry-javascript icon indicating copy to clipboard operation
sentry-javascript copied to clipboard

[JavaScript] Nuxt SDK

Open stephanie-anderson opened this issue 2 years ago • 42 comments

[!IMPORTANT]
This issue is tracking progress on the Nuxt SDK. If you find bugs or problems with the @sentry/nuxt package please open a separate issue. Thank you!

New SDK for https://nuxt.com/

There is an existing discussion: Sentry SDK for Nuxt

Nuxt uses nitro as their server, this means we'll need to have nitro support. It might make sense for us to create an OpenTelemetry instrumentation for nitro. It will also be valuable to add similar instrumentation for the other libraries Nuxt relies on:

  • crossws: their websocket wrapper: https://crossws.unjs.io/
  • db0: their database wrapper: https://github.com/unjs/db0
  • unstorage: their key/value storage wrapper: https://github.com/unjs/unstorage
### Alpha
- [ ] https://github.com/getsentry/sentry-javascript/issues/12572
- [x] Add client (vue) instrumentation
- [x] sentryNuxtPlugin for error handling
- [ ] https://github.com/getsentry/sentry-javascript/issues/12795
- [ ] https://github.com/getsentry/sentry-javascript/issues/12759
- [x] Add E2E tests
- [x] Add craft entry for Nuxt SDK
- [ ] https://github.com/getsentry/sentry-javascript/issues/13017
- [ ] https://github.com/getsentry/sentry-javascript/issues/13067
- [ ] https://github.com/getsentry/sentry-javascript/issues/13097
### Beta
- [ ] Create Nuxt Platfrom in Sentry
- [ ] https://github.com/getsentry/sentry-javascript/issues/13383
- [ ] https://github.com/getsentry/sentry-javascript/issues/13239
- [ ] https://github.com/getsentry/platformicons/issues/174
- [ ] https://github.com/getsentry/sentry-javascript/issues/13380
- [ ] https://github.com/getsentry/sentry-javascript/pull/13583
- [x] Nuxt: Vue component tracking https://github.com/getsentry/sentry-javascript/pull/13633
- [ ] https://github.com/getsentry/sentry-javascript/issues/13943
- [ ] Vercel Function Deployment: https://github.com/getsentry/sentry-javascript/pull/13986
- [ ] https://github.com/getsentry/sentry-javascript/issues/13997
### Stable Release
- [ ] Nitro Route Parametrization
- [ ] Nuxt Setup Wizard
- [ ] Ensure deployment to Netlify works
- [x] Nuxt 4 Support https://github.com/getsentry/sentry-javascript/pull/13799
- [ ] https://github.com/getsentry/sentry-javascript/issues/13949
- [ ] https://github.com/getsentry/sentry-javascript/issues/13917
- [ ] Nuxt: Server side works in development mode
### Nice to have/Stretch Goals
- [ ] Add Nuxt pages router instrumentation
- [ ] https://github.com/getsentry/sentry-javascript/issues/13813
- [ ] Add support for Nuxt Layers
- [ ] Add worker runtime support
- [ ] (if needed) Add native Nitro server engine support
- [ ] (if needed) Instrument Nuxt $fetch
- [ ] Instrument `useError` composable
- [ ] https://github.com/getsentry/sentry-javascript/issues/13341

stephanie-anderson avatar Sep 22 '23 14:09 stephanie-anderson

See https://github.com/getsentry/sentry-javascript/discussions/6929

AbhiPrasad avatar Sep 25 '23 14:09 AbhiPrasad

If you need insights from the Nuxt team at any time, please don't hesitate to reach out! 🙏

TheAlexLichter avatar Jun 20 '24 08:06 TheAlexLichter

This is such a great news!

It would be ideal that it would work on all envs. Nuxt works very well on the edge (cloudflare workers, netlify edge, etc), however not all libraries are compatible as there are some restrictions (no eval, no new Function(), etc).

It would be great if sentry/nuxt would work everywhere from day one.

cosbgn avatar Jun 24 '24 09:06 cosbgn

@cosbgn Thanks for the input! Which libraries do you mean with "not all libraries are compatible"?

s1gr1d avatar Jun 24 '24 11:06 s1gr1d

@cosbgn Thanks for the input! Which libraries do you mean with "not all libraries are compatible"?

Hi @s1gr1d, I don't have an extensive list, but for example AJV doesn't work. Workers don't use node, they use their own runtime (workerd) which is limited to web standards (similarly to deno).

I think if you use only sentry/core it should work as it's used by toucan-js which is an unofficial client for cloudflare workers. I think sentry/node won't work by default, but I might be wrong here.

cosbgn avatar Jun 24 '24 11:06 cosbgn

This is of course for the backend part of nuxt, i.e. nitro. On the frontend sentry/vue should work perfectly.

cosbgn avatar Jun 24 '24 11:06 cosbgn

I use Sentry on my APIs (fullstack Nuxt 3 deployment to Cloudflare pages) with the sentry/browser package on the API side to get around edge restrictions.

The context Sentry devs, for cosbgn's comment, is that Nuxt 3 was built with the "deploy anywhere" ethos, so all the core packages and (new) community modules are designed to be runtime agnostic. That's where https://unjs.io/ was born from.

I initially followed this guide if it helps at all with the PR in general https://www.lichter.io/articles/nuxt3-sentry-recipe (written by a core Nuxt 3 dev)

alexcroox avatar Jun 24 '24 12:06 alexcroox

While we may not support worker (WinterCG) runtimes from the start we will look into it eventually. We are planning to release the SDK iteratively and in stages. Prioritization of worker runtime support depends of course a bit on the demand. I added an item to the list to track. Technically we have all the building blocks available.

lforst avatar Jun 24 '24 12:06 lforst

I don't have any specific data, but from my understanding a big percent of nuxt apps are deployed on the edge (vercel-edge, workers, netlify edge, etc) as you get better performance for lower costs, and Nuxt pretty much "guarantees" that it will work on the edge, so it's an obvious solution.

I understand if you decide not to prioritize it, I just wanted to let you know that it would be great to have it from day one. It might be as simple as using sentry/core rather than sentry/node (I don't know, just an example).

Anyways, thanks for the first party package, love sentry and I would love to be able to add it to Nuxt easily!

cosbgn avatar Jun 24 '24 12:06 cosbgn

Great initiative!

Could we also make sure that errors before the hydration are also handled?

gloompiq avatar Jun 28 '24 11:06 gloompiq

We want to monitor as many as possible. The first release of the SDK will cover monitoring the majority of errors and we will definitely improve it over time

s1gr1d avatar Jun 28 '24 11:06 s1gr1d

It would be great if this module could integrate @sentry/vite-plugin. There could be a flag uploadSourcemaps, which automatically sets sourcemap: true in Nuxt config and configures sentryVitePlugin to upload sourcemaps. An option to delete public source maps at the end of the build would be appreciated. The sourcemaps.filesToDeleteAfterUpload option only deletes files after uploading the sourcemaps, but sourcemaps should always be removed when the flag is set, even if no sourcemaps were uploaded.

P4sca1 avatar Jul 17 '24 15:07 P4sca1

@P4sca1 matching how our SvelteKit SDK works with vite plugin and our Next.js SDK works with our webpack plugin, we'll definitely have 1st class integration with the vite plugin in the Nuxt SDK!

For now you can use the sentry wizard which will automatically add the vite plugin to your vite config, but you'll still have to supply the options yourself.

npx @sentry/wizard@latest -i sourcemaps

AbhiPrasad avatar Jul 18 '24 01:07 AbhiPrasad

Hi, great initiative! Is there any ETA on this project? 🙂

nkmnz avatar Aug 05 '24 22:08 nkmnz

Good news 🎉 You can already use the Nuxt SDK, there should not be breaking changes as of now. Version 8.23.0 is a good version to start using it and it offers new enhancements like filtering out transactions of build assets (_nuxt). Keep in mind the SDK is optimized for the production build (nuxt build -> nuxt preview). The readme gives you the setup instructions for the time being. The official docs are coming this week.

I would say it is in late alpha state as some features are still being implemented/tested and by having people already using the SDK we can get a solid understanding of which features are still missing or not working correctly.

s1gr1d avatar Aug 06 '24 07:08 s1gr1d

Awesome, good news indeed! Thank you!

nkmnz avatar Aug 06 '24 08:08 nkmnz

Maybe this is not the place to ask, feel free to delete, but I can't get past the part where you import the instrument when running yarn preview:

TypeError [ERR_INVALID_MODULE_SPECIFIER]: Invalid module ".output/public/instrument.server.mjs" is not a valid package name imported from ...

Any ideas?

"nuxt": "^3.12.4", "@sentry/nuxt": "^8.24.0",

--- EDIT ---

I tried it on a clean project and it seems to work fine, so there's something up in my project!

--- EDIT 2 ---

Fixed with:

    "preview": "cross-env NODE_OPTIONS=\"--import file://$(pwd)/.output/public/instrument.server.mjs\" nuxt preview",

max-arias avatar Aug 07 '24 15:08 max-arias

@max-arias Thanks for reporting! Please open a new issue as it helps us avoid some back and fourth asking what you did and how you set up the SDK and so on. We'll take a look!

lforst avatar Aug 07 '24 17:08 lforst

Any updates on when sourcemap support will be added to the SDK?

BlazingTide avatar Aug 11 '24 19:08 BlazingTide

Source maps should already work for the client-side issues (docs here). Server-side source maps are coming soon.

s1gr1d avatar Aug 12 '24 07:08 s1gr1d

"Add an --import flag to the NODE_OPTIONS environment variable wherever you run your application. For local previews, update your nuxt preview script in the package.json (see below). Also, ensure this environment variable is set in your deployment environment, such as on Netlify or Vercel."

Does this mean i should add it

"build": "NITRO_PORT=4000 NITRO_HOST=0.0.0.0 nuxt build", "dev": "NITRO_PORT=3000 NITRO_HOST=0.0.0.0 NODE_TLS_REJECT_UNAUTHORIZED=0 nuxt dev", "generate": "nuxt generate", "preview": "nuxt preview", "postinstall": "nuxt prepare", "start": "NITRO_PORT=4000 NITRO_HOST=0.0.0.0 node .output/server/index.mjs"

To all of these??

rnenjoy avatar Aug 12 '24 08:08 rnenjoy

Would be great if, within the sentry.client.config.ts file, we would able to use the runtime config:

https://nuxt.com/docs/api/composables/use-runtime-config

Example from other module: https://formkit.com/getting-started/installation#using-environment-variables-in-formkitconfigts

The code below

import * as Sentry from '@sentry/nuxt'

Sentry.init({
  enabled: process.env.NUXT_PUBLIC_SENTRY_ENABLED,
})

Would then become:

import * as Sentry from '@sentry/nuxt'

export default defineSentryConfig(() => {

  const config = useRuntimeConfig()

  Sentry.init({
    enabled: config.public.sentry.enabled,
  })
})

darthf1 avatar Aug 12 '24 08:08 darthf1

Would be great if, with the sentry.client.config.ts file, we would able to use the runtime config

Ideally I'd prefer it if the sentry.client.config.ts was not required at all and all configutation was done in the 'sentry' key of the Nuxt Config.

luc122c avatar Aug 12 '24 09:08 luc122c

@rnenjoy you would have to update those two scripts:

"preview": "NODE_OPTIONS='--import ./public/instrument.server.mjs' nuxt preview",
"start": "NITRO_PORT=4000 NITRO_HOST=0.0.0.0 node  --import .output/public/instrument.server.mjs .output/server/index.mjs"

Those scripts are using the generated build output of nuxt. The Sentry Nuxt SDK is optimized for the production build, so you only have to add it here. Without this, the server-part is not fully instrumented.


@darthf1 @luc122c We opted for having an external file as this gives you the possibility to pass functions like beforeSend (docs here). This would not be possible in the nuxt config. The nuxt config is only intended for Sentry build-time options like sourcemaps.

And thanks for providing the formkit example, this looks like a nice API. We are going to have a look at this and see if we can implement something like this as well!

s1gr1d avatar Aug 12 '24 15:08 s1gr1d

Hi @s1gr1d , thank you for the hard work so far :-) I have two questions with regard to the server instrumentation:

  1. I'd like to better understand the reasoning behind putting the server instrumentation into a file in the public folder. Nuxt hosts all files in public on the root of the project, e.g. ~/public/logo.svg would be available in the browser at http://localhost:3000/logo.svg (or at the respective production URL). Is there any need to publish the instrumentation file via a web server if it's only used when running the start or preview scripts from package.json? I guess the idiosyncratic way would be to put it into a scripts folder.

  2. Also, did you consider the alternative to initialize Sentry inside of the server-plugin as @manniL did here? We could pass all options from the nuxt config file, which could include functions as well?

nkmnz avatar Aug 15 '24 20:08 nkmnz

Hey, thank you for your feedback!

@s1gr1d is out today, she can answer in more detail on Monday! Generally speaking, the main challenge we have is that we need to run Sentry in an --import flag, in order for ESM instrumentation to work. This means that you cannot just inject some script in v8 of the SDK into the server and have everything instrumented correctly, but you need to configure this at app boot time - which means you need to have the file to reference/import at the time that the nuxt server is started.

I am not saying that the public/ folder is necessarily the ideal solution, but this is the main constraint we have to work around - if we find a better way to do this, we'd definitely be happy to! We are still investigating different approaches here :)

mydea avatar Aug 16 '24 06:08 mydea

Would be great if, within the sentry.client.config.ts file, we would able to use the runtime config:

https://nuxt.com/docs/api/composables/use-runtime-config

Example from other module: https://formkit.com/getting-started/installation#using-environment-variables-in-formkitconfigts

The code below

import * as Sentry from '@sentry/nuxt'

Sentry.init({ enabled: process.env.NUXT_PUBLIC_SENTRY_ENABLED, })

Would then become:

import * as Sentry from '@sentry/nuxt'

export default defineSentryConfig(() => {

const config = useRuntimeConfig()

Sentry.init({ enabled: config.public.sentry.enabled, }) })

Yeah, because right now there is no way to use Nuxt public config right?

AlejandroAkbal avatar Aug 17 '24 12:08 AlejandroAkbal

@nkmnz It is in the public folder right now, because the file needs to be added to the build output as it is (to reference it in the node option input). But I agree that this is not 100% ideal and this will be changed probably.

About your 2. point: Do you mean creating a server-plugin yourself? The SDK already adds a server-plugin with the necessary hooks. But the initialization takes place in the instrument file and is loaded with the node option import. It has to be added with import to initialize sentry at the very start. This is needed for the otel instrumentation to work correctly in ESM (which Nuxt is). Without initializing the SDK at the very start, only the basic http instrumentation will work.

s1gr1d avatar Aug 26 '24 07:08 s1gr1d

@nkmnz It is in the public folder right now, because the file needs to be added to the build output as it is (to reference it in the node option input). But I agree that this is not 100% ideal and this will be changed probably.

About your 2. point: Do you mean creating a server-plugin yourself? The SDK already adds a server-plugin with the necessary hooks. But the initialization takes place in the instrument file and is loaded with the node option import. It has to be added with import to initialize sentry at the very start. This is needed for the otel instrumentation to work correctly in ESM (which Nuxt is). Without initializing the SDK at the very start, only the basic http instrumentation will work.

Hi @s1gr1d,

can't we use late initiliazation to solve this? When I understand the article correctly that would mean we can invoke Sentry.init at a later point, even within a server plugin removing the need for the file inside the public folder directory.

Anton-Plagemann avatar Aug 26 '24 08:08 Anton-Plagemann

Yes, something like this could work. I am just trying different approaches.

s1gr1d avatar Aug 26 '24 08:08 s1gr1d