Skip to content

Conversation

@schplitt
Copy link

🔗 Linked issue

resolves #7

📚 Description

This PR adds support for early nitro v3 alpha versions under the evlog/nitrov3 scope.
Hope that is alright.

I move shared nitro utilities to a seperate file.
I have adjusted the docs aswell to add a note and a playground.
Nitrov3 currently seems to have issues with runtime config support in monorepos but it should work correctly in a new project.
I am not very familiar with bun so I couldn't get the imports from the node_modules to work and used a relative path instead.
For that reason also please check if I integrated it correctly into the build config.

Please see if you would like to have anything changed!

📝 Checklist

  • I have linked an issue or discussion.
  • I have updated the documentation accordingly.

@vercel
Copy link

vercel bot commented Jan 27, 2026

@schplitt is attempting to deploy a commit to the HRCD Projects Team on Vercel.

A member of the Team first needs to authorize it.

@github-actions
Copy link

github-actions bot commented Jan 27, 2026

Thank you for following the naming conventions! 🙏

@HugoRCD
Copy link
Owner

HugoRCD commented Jan 27, 2026

@schplitt I don't know if it's better, but I'd prefer to have an entry point that looks more like 'evlog/nitro/v3'. I don't really like having nitrov3 attached and it will be easier to migrate later by just removing /v3 and maybe replace v3 with v2 for migration 🤔. Otherwise, we'd also need a more 'complete' playground and tests as well! (If you don't have time, I can take care of it later)

@schplitt
Copy link
Author

@schplitt I don't know if it's better, but I'd prefer to have an entry point that looks more like 'evlog/nitro/v3'. I don't really like having nitrov3 attached and it will be easier to migrate later by just removing /v3 and maybe replace v3 with v2 for migration 🤔. Otherwise, we'd also need a more 'complete' playground and tests as well! (If you don't have time, I can take care of it later)

Should the 'complete' playground be like v2 or even more extensive?

@HugoRCD
Copy link
Owner

HugoRCD commented Jan 27, 2026

@schplitt I don't know if it's better, but I'd prefer to have an entry point that looks more like 'evlog/nitro/v3'. I don't really like having nitrov3 attached and it will be easier to migrate later by just removing /v3 and maybe replace v3 with v2 for migration 🤔. Otherwise, we'd also need a more 'complete' playground and tests as well! (If you don't have time, I can take care of it later)

Should the 'complete' playground be like v2 or even more extensive?

Ideally similar, but otherwise just a little less comprehensive is fine with me too. It's just so we can easily launch the app and quickly test that everything works without having to do too much setup.

@schplitt
Copy link
Author

Alright
I'll take care of that

@schplitt
Copy link
Author

Improved the playground to serve a basic UI to visualize the error aswell

Also moved nitrov3 to nitro/v3 in dist 🙂

@schplitt
Copy link
Author

schplitt commented Jan 27, 2026

I noticed that in v3 the error is transformed into an unhandled HTTPError before we have access to it
So this isn't actually working yet.

We would need to overwrite the entire error handler to be able to handle EvlogErrors correctly
Or have EvlogErrors extend HTTPErrors in nitro v3

@HugoRCD HugoRCD changed the title feat: add support for nitrov3 feat: add support for nitro v3 Jan 27, 2026
@HugoRCD
Copy link
Owner

HugoRCD commented Jan 27, 2026

I noticed that in v3 the error is transformed into an unhandled HTTPError before we have access to it So this isn't actually working yet.

We would need to overwrite the entire error handler to be able to handle EvlogErrors correctly Or have EvlogErrors extend HTTPErrors in nitro v3

I'll try to see how we can do that too

@pkg-pr-new
Copy link

pkg-pr-new bot commented Jan 27, 2026

npm i https://pkg.pr.new/evlog@8

commit: 0994c10

@vercel
Copy link

vercel bot commented Jan 27, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
evlog-docs Ready Ready Preview, Comment Jan 31, 2026 1:35pm

@HugoRCD
Copy link
Owner

HugoRCD commented Jan 27, 2026

I just realized that I'm not even sure if this is supposed to work, or if it will ever work 😅

CleanShot 2026-01-27 at 22 09 21@2x

@schplitt
Copy link
Author

I just realized that I'm not even sure if this is supposed to work, or if it will ever work 😅

CleanShot 2026-01-27 at 22 09 21@2x

What exactly are you referring to?

@HugoRCD
Copy link
Owner

HugoRCD commented Jan 28, 2026

I just realized that I'm not even sure if this is supposed to work, or if it will ever work 😅
CleanShot 2026-01-27 at 22 09 21@2x

What exactly are you referring to?

I don't know if this syntax, where you put a plugin (imported from npm) directly into the plugin array, works. The documentation doesn't mention it

@schplitt
Copy link
Author

I am not sure what the future plans for nuxt and evlog are but as nitro will become framework agnostic and interop with vite plugins, maybe it would be a nice Idea to experiment with nitro modules:
nitrojs/nitro#3680

So that it could also be used with tanstack, etc.?
Though just an idea.

Let me know what your plans are going forward regarding nitro v3 and I'll see how I can help🙂

@HugoRCD
Copy link
Owner

HugoRCD commented Jan 28, 2026

I am not sure what the future plans for nuxt and evlog are but as nitro will become framework agnostic and interop with vite plugins, maybe it would be a nice Idea to experiment with nitro modules: nitrojs/nitro#3680

So that it could also be used with tanstack, etc.? Though just an idea.

Let me know what your plans are going forward regarding nitro v3 and I'll see how I can help🙂

That's exactly the goal, to allow everyone to use evlog on all frameworks (and standalone) that support Nitro and to have the best possible user experience

@schplitt
Copy link
Author

I just realized that I'm not even sure if this is supposed to work, or if it will ever work 😅
CleanShot 2026-01-27 at 22 09 21@2x

What exactly are you referring to?

I don't know if this syntax, where you put a plugin (imported from npm) directly into the plugin array, works. The documentation doesn't mention it

Nitro lets the bundler resolve the plugins by using virtual imports.
so plugins: ["evlog/nitro/v3] should work correctly

https://github.com/nitrojs/nitro/blob/main/src/build/virtual/plugins.ts

@HugoRCD
Copy link
Owner

HugoRCD commented Jan 28, 2026

@schplitt Oh, nice! So I think we should implement it like that, and clean up the repo to have a Nitro v2 playground and a Nitro v3 (update the PR with the latest features I added)

@schplitt
Copy link
Author

I noticed that in v3 the error is transformed into an unhandled HTTPError before we have access to it So this isn't actually working yet.
We would need to overwrite the entire error handler to be able to handle EvlogErrors correctly Or have EvlogErrors extend HTTPErrors in nitro v3

I'll try to see how we can do that too

What about your preferred solution for this?

@HugoRCD
Copy link
Owner

HugoRCD commented Jan 28, 2026

I noticed that in v3 the error is transformed into an unhandled HTTPError before we have access to it So this isn't actually working yet.
We would need to overwrite the entire error handler to be able to handle EvlogErrors correctly Or have EvlogErrors extend HTTPErrors in nitro v3

I'll try to see how we can do that too

What about your preferred solution for this?

So I would lean towards "simplicity" and extend HTTPError

@schplitt
Copy link
Author

schplitt commented Jan 28, 2026

I've looked into this a bit.
I think there is not really an "easy" way to do this.

First, we would make Evlog dependend on H3 v2 HTTPError which I think is incompatible with Nuxt and Nitro v2.

Second, the HTTPError interface is a bit different then what is currently expeced (e.g. extra body property for the returned response). It may be best to create another utility for Nitro v3 and export it from there to not have Nitro v2 and Nuxt be dependend on H3 v2.

@schplitt schplitt closed this Jan 28, 2026
@schplitt schplitt reopened this Jan 28, 2026
@schplitt
Copy link
Author

schplitt commented Jan 31, 2026

So I've finally had time to fix up the nitro/v3 functionality.

Now it uses H3's HTTPError. Though there are still a couple of issues that need to be resolved:

  1. Runtime Config Bundling Issue

When the plugin for Nitro v3 is bundled, it also bundles the reference to useRuntimeConfig() which results in it not actually having access to the correct runtime config but a mock. It also causes this warning in the terminal:

WARN  Nitro runtime imports detected without a builder or Nitro plugin. A stub implementation will be used.

TBH I have not yet found a better solution than actually copying the file into the package and having nitro transpile it at run/build time. But the necessary imports from evlog would need to be available from the package itself, though that seems to be possible. This would mean some logic cannot be shared (e.g., the shouldLog function).

Actually I think we can just mark nitro/runtime-config as external. This way the import is resolved by nitro at run/buildtime.

  1. Error Name Display

When the Error is logged, it still says HTTPError in the log message as we cannot overwrite the name of HTTPError:

16:42:33.410 ERROR [app] PUT /api/test/update 403 in 261ms
  ├─ requestId: b191342e-c394-4d2e-a5b3-b35df0574bb2
  ├─ user: id=999
  ├─ action: update_item
  ├─ item: name=My Item version=2.0
  ├─ validation: checked=true
  ├─ permissions: checked=true hasUpdate=false requiredRole=admin
  └─ error: name=HTTPError message=Update failed stack=HTTPError: Update failed
    at createError (file:///home/schplitt/vsc/evlog/packages/evlog/dist/nitro/v3/plugin.mjs:56:10)
    at file:///home/schplitt/vsc/evlog/apps/nitro-v3-playground/node_modules/.nitro/dev/index.mjs:819:9
Note: In Nitro v3, every Error besides HTTPError is automatically marked as unhandled which causes an even bigger error log
EvlogError: Update failed
    at createError (file:///home/schplitt/vsc/evlog/packages/evlog/dist/nitro/v3/plugin.mjs:59:10)
    at file:///home/schplitt/vsc/evlog/apps/nitro-v3-playground/node_modules/.nitro/dev/index.mjs:819:9 {
  cause: EvlogError: Update failed
      at createError (file:///home/schplitt/vsc/evlog/packages/evlog/dist/nitro/v3/plugin.mjs:59:10)
      at file:///home/schplitt/vsc/evlog/apps/nitro-v3-playground/node_modules/.nitro/dev/index.mjs:819:9 {
    cause: {
      cause: undefined,
      body: [Object],
      statusCode: 403,
      unhandled: false
    },
    status: 403,
    statusText: undefined,
    headers: undefined,
    data: undefined,
    body: {
      why: 'Insufficient permissions to update this resource',
      fix: 'Request admin privileges or contact your team lead',
      link: 'https://docs.example.com/permissions'
    },
    unhandled: false,
    why: 'Insufficient permissions to update this resource',
    fix: 'Request admin privileges or contact your team lead',
    link: 'https://docs.example.com/permissions'
  },
  status: 403,
  statusText: undefined,
  headers: undefined,
  data: undefined,
  body: {
    why: 'Insufficient permissions to update this resource',
    fix: 'Request admin privileges or contact your team lead',
    link: 'https://docs.example.com/permissions'
  },
  unhandled: true
}
16:39:56.331 ERROR [app] PUT /api/test/update 403 in 261ms
  ├─ requestId: 5bac1ec9-c6d6-47f2-9d56-da1b3a48e82c
  ├─ user: id=999
  ├─ action: update_item
  ├─ item: name=My Item version=2.0
  ├─ validation: checked=true
  ├─ permissions: checked=true hasUpdate=false requiredRole=admin
  └─ error: name=HTTPError message=Update failed stack=EvlogError: Update failed
    at createError (file:///home/schplitt/vsc/evlog/packages/evlog/dist/nitro/v3/plugin.mjs:59:10)
    at file:///home/schplitt/vsc/evlog/apps/nitro-v3-playground/node_modules/.nitro/dev/index.mjs:819:9

 ERROR  [request error] [unhandled] [PUT] http://localhost:3000/api/test/update

 
ℹ HTTPError: Update failed

 ⁃ at createError (/home/schplitt/vsc/evlog/packages/evlog/dist/nitro/v3/plugin.mjs:59:10)

   54 ┃      }
   55 ┃      return lines.join("\n");
   56 ┃    }
   57 ┃  }
   58 ┃  function createError(options) {
 ❯ 59 ┃    return new EvlogError(options);
   60 ┃  }
   61 ┃  const createEvlogError = createError;
   62 ┃  
   63 ┃  const plugin = definePlugin((nitroApp) => {
   64 ┃    const config = useRuntimeConfig();

 ⁃ (node_modules/.nitro/dev/index.mjs:819:9)

[CAUSE]
EvlogError {
  stack: 'Update failed\n' +
  'at createError (/home/schplitt/vsc/evlog/packages/evlog/dist/nitro/v3/plugin.mjs:59:10)\n' +
  'at ./node_modules/.nitro/dev/index.mjs:819:9)',
  message: 'Update failed',
  cause: {
    cause: undefined,
    body: [Object],
    statusCode: 403,
    unhandled: false,
  },
  status: 403,
  statusText: undefined,
  headers: undefined,
  data: undefined,
  body: {
    why: 'Insufficient permissions to update this resource',
    fix: 'Request admin privileges or contact your team lead',
    link: 'https://docs.example.com/permissions',
  },
  unhandled: false,
  why: 'Insufficient permissions to update this resource',
  fix: 'Request admin privileges or contact your team lead',
  link: 'https://docs.example.com/permissions',
}

It may be a bit confusing why the error from createError shows as HTTPError in the logs.

  1. Missing body

Currently Nitro v3 doesn't correctly pass the body back to the user (why, link, ...). But this is already being fixed.

Any wishes on how to best go forward with this @HugoRCD ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

NitroV3 support

2 participants