-
-
Notifications
You must be signed in to change notification settings - Fork 243
fix(nuxt): skip generation during prepare if no input & config types #2618
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
base: main
Are you sure you want to change the base?
Changes from all commits
f4ef6f8
5868419
8beb2e7
ce81209
8baac38
db714c7
49d1352
93e357b
19fa633
ac84c29
eb48124
2f01555
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -1,6 +1,6 @@ | ||||||||||||||||||||
--- | ||||||||||||||||||||
title: Nuxt v3 Client | ||||||||||||||||||||
description: Generate a type-safe Nuxt v3 client from OpenAPI with the Nuxt client for openapi-ts. Fully compatible with validators, transformers, and all core features. | ||||||||||||||||||||
title: Nuxt Client | ||||||||||||||||||||
description: Generate a type-safe Nuxt client from OpenAPI with the Nuxt client for openapi-ts. Fully compatible with validators, transformers, and all core features. | ||||||||||||||||||||
--- | ||||||||||||||||||||
|
||||||||||||||||||||
<script setup lang="ts"> | ||||||||||||||||||||
|
@@ -9,8 +9,7 @@ import VersionLabel from '@components/VersionLabel.vue'; | |||||||||||||||||||
</script> | ||||||||||||||||||||
|
||||||||||||||||||||
<Heading> | ||||||||||||||||||||
<h1>Nuxt<span class="sr-only"> v3</span></h1> | ||||||||||||||||||||
<VersionLabel value="v3" /> | ||||||||||||||||||||
<h1>Nuxt</h1> | ||||||||||||||||||||
</Heading> | ||||||||||||||||||||
|
||||||||||||||||||||
::: warning | ||||||||||||||||||||
|
@@ -25,7 +24,6 @@ The Nuxt client for Hey API generates a type-safe client from your OpenAPI spec, | |||||||||||||||||||
|
||||||||||||||||||||
## Features | ||||||||||||||||||||
|
||||||||||||||||||||
- Nuxt v3 support | ||||||||||||||||||||
- seamless integration with `@hey-api/openapi-ts` ecosystem | ||||||||||||||||||||
- type-safe response data and errors | ||||||||||||||||||||
- response data validation and transformation | ||||||||||||||||||||
|
@@ -36,7 +34,33 @@ The Nuxt client for Hey API generates a type-safe client from your OpenAPI spec, | |||||||||||||||||||
|
||||||||||||||||||||
## Installation | ||||||||||||||||||||
|
||||||||||||||||||||
Start by adding `@hey-api/nuxt` to your dependencies. | ||||||||||||||||||||
### Automatic installation | ||||||||||||||||||||
|
||||||||||||||||||||
Start by installing the `@hey-api/nuxt` Nuxt module. | ||||||||||||||||||||
|
||||||||||||||||||||
::: code-group | ||||||||||||||||||||
|
||||||||||||||||||||
```sh [npm] | ||||||||||||||||||||
npx nuxi module add @hey-api/nuxt | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
```sh [pnpm] | ||||||||||||||||||||
pnpx nuxi module add @hey-api/nuxt | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
```sh [yarn] | ||||||||||||||||||||
yarn dlx nuxi module @hey-api/nuxt | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
```sh [bun] | ||||||||||||||||||||
bunx nuxi module add @hey-api/nuxt | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
::: | ||||||||||||||||||||
|
||||||||||||||||||||
### Manual installation | ||||||||||||||||||||
|
||||||||||||||||||||
Add `@hey-api/nuxt` to your dependencies. | ||||||||||||||||||||
|
||||||||||||||||||||
::: code-group | ||||||||||||||||||||
|
||||||||||||||||||||
|
@@ -58,76 +82,135 @@ bun add @hey-api/nuxt | |||||||||||||||||||
|
||||||||||||||||||||
::: | ||||||||||||||||||||
|
||||||||||||||||||||
In your [configuration](/openapi-ts/get-started), add `@hey-api/client-nuxt` to your plugins and you'll be ready to generate client artifacts. :tada: | ||||||||||||||||||||
|
||||||||||||||||||||
::: code-group | ||||||||||||||||||||
Then, add it to the `modules` in your `nuxt.config.ts`: | ||||||||||||||||||||
|
||||||||||||||||||||
```js [config] | ||||||||||||||||||||
export default { | ||||||||||||||||||||
input: 'hey-api/backend', // sign up at app.heyapi.dev | ||||||||||||||||||||
output: 'src/client', | ||||||||||||||||||||
plugins: ['@hey-api/client-nuxt'], // [!code ++] | ||||||||||||||||||||
}; | ||||||||||||||||||||
```ts | ||||||||||||||||||||
export default defineNuxtConfig({ | ||||||||||||||||||||
modules: [ | ||||||||||||||||||||
'@hey-api/nuxt', // [!code ++] | ||||||||||||||||||||
], | ||||||||||||||||||||
}); | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
```sh [cli] | ||||||||||||||||||||
npx @hey-api/openapi-ts \ | ||||||||||||||||||||
-i hey-api/backend \ | ||||||||||||||||||||
-o src/client \ | ||||||||||||||||||||
-c @hey-api/client-nuxt # [!code ++] | ||||||||||||||||||||
## Getting started | ||||||||||||||||||||
|
||||||||||||||||||||
Set an [input](/openapi-ts/configuration/input) within `nuxt.config.ts`, then start the Nuxt dev server. | ||||||||||||||||||||
|
||||||||||||||||||||
```ts | ||||||||||||||||||||
export default defineNuxtConfig({ | ||||||||||||||||||||
heyApi: { | ||||||||||||||||||||
config: { | ||||||||||||||||||||
input: './path/to/openapi.json', // [!code ++] | ||||||||||||||||||||
}, | ||||||||||||||||||||
}, | ||||||||||||||||||||
}); | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
::: | ||||||||||||||||||||
The generated client can be accessed from `#hey-api/`. | ||||||||||||||||||||
|
||||||||||||||||||||
```ts | ||||||||||||||||||||
import { client } from '#hey-api/client.gen'; | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
::: tip | ||||||||||||||||||||
|
||||||||||||||||||||
If you add `@hey-api/nuxt` to your Nuxt modules, this step is not needed. | ||||||||||||||||||||
The `@hey-api/client-nuxt` plugin is automatically added. | ||||||||||||||||||||
|
||||||||||||||||||||
::: | ||||||||||||||||||||
|
||||||||||||||||||||
### Options | ||||||||||||||||||||
|
||||||||||||||||||||
### `alias` | ||||||||||||||||||||
|
||||||||||||||||||||
Configure an [alias](https://nuxt.com/docs/api/nuxt-config#alias) to access the Hey API client. | ||||||||||||||||||||
|
||||||||||||||||||||
Defaults to `#hey-api` | ||||||||||||||||||||
|
||||||||||||||||||||
### `autoImports` | ||||||||||||||||||||
|
||||||||||||||||||||
Adds the generated SDK items to auto imports. Defaults to `true`. | ||||||||||||||||||||
|
||||||||||||||||||||
#### `config` | ||||||||||||||||||||
|
||||||||||||||||||||
Configuration to pass to `@hey-api/openapi-ts`. | ||||||||||||||||||||
|
||||||||||||||||||||
- [input](/openapi-ts/configuration/input) | ||||||||||||||||||||
- [output](/openapi-ts/configuration/output) | ||||||||||||||||||||
- Defaults to `.nuxt/client` | ||||||||||||||||||||
- [parser](/openapi-ts/configuration/parser) | ||||||||||||||||||||
- [plugins](/openapi-ts/plugins/transformers) | ||||||||||||||||||||
|
||||||||||||||||||||
## Configuration | ||||||||||||||||||||
|
||||||||||||||||||||
The Nuxt client is built as a thin wrapper on top of Nuxt, extending its functionality to work with Hey API. If you're already familiar with Nuxt, configuring your client will feel like working directly with Nuxt. | ||||||||||||||||||||
When we configured the Nuxt module above, it created a [`client.gen.ts`](/openapi-ts/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. | ||||||||||||||||||||
|
||||||||||||||||||||
When we installed the client above, it created a [`client.gen.ts`](/openapi-ts/output#client) file. You will most likely want to configure the exported `client` instance. There are two ways to do that. | ||||||||||||||||||||
The Nuxt client is built as a thin wrapper on top of Nuxt, extending its functionality to work with Hey API. If you're already familiar with Nuxt, configuring your client will feel like working directly with Nuxt. | ||||||||||||||||||||
|
||||||||||||||||||||
### `setConfig()` | ||||||||||||||||||||
|
||||||||||||||||||||
This is the simpler approach. You can call the `setConfig()` method at the beginning of your application or anytime you need to update the client configuration. You can pass any Nuxt configuration option to `setConfig()`, and even your own [`$fetch`](#custom-fetch) implementation. | ||||||||||||||||||||
|
||||||||||||||||||||
```js | ||||||||||||||||||||
import { client } from 'client/client.gen'; | ||||||||||||||||||||
::: code-group | ||||||||||||||||||||
|
||||||||||||||||||||
client.setConfig({ | ||||||||||||||||||||
baseURL: 'https://example.com', | ||||||||||||||||||||
```vue [app.vue] | ||||||||||||||||||||
<script setup lang="ts"> | ||||||||||||||||||||
import { client } from '#hey-api/client.gen'; | ||||||||||||||||||||
|
||||||||||||||||||||
await callOnce(async () => { | ||||||||||||||||||||
client.setConfig({ | ||||||||||||||||||||
baseURL: 'https://example.com', | ||||||||||||||||||||
}); | ||||||||||||||||||||
}); | ||||||||||||||||||||
</script> | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
::: | ||||||||||||||||||||
|
||||||||||||||||||||
The disadvantage of this approach is that your code may call the `client` instance before it's configured for the first time. Depending on your use case, you might need to use the second approach. | ||||||||||||||||||||
|
||||||||||||||||||||
### Runtime API | ||||||||||||||||||||
|
||||||||||||||||||||
Since `client.gen.ts` is a generated file, we can't directly modify it. Instead, we can tell our configuration to use a custom file implementing the Runtime API. We do that by specifying the `runtimeConfigPath` option. | ||||||||||||||||||||
|
||||||||||||||||||||
```js | ||||||||||||||||||||
::: code-group | ||||||||||||||||||||
|
||||||||||||||||||||
```ts [nuxt] | ||||||||||||||||||||
export default defineNuxtConfig({ | ||||||||||||||||||||
heyApi: { | ||||||||||||||||||||
config: { | ||||||||||||||||||||
input: 'hey-api/backend', // sign up at app.heyapi.dev | ||||||||||||||||||||
plugins: [ | ||||||||||||||||||||
{ | ||||||||||||||||||||
name: '@hey-api/client-nuxt', | ||||||||||||||||||||
runtimeConfigPath: './shared/lib/hey-api.ts', // [!code ++] | ||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why do you sometimes use the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The runtime config path should be within Originally I thought the generated Nuxt client could be used in both the frontend and server routes, so I figured the shared directory would be the best Nuxt folder for it. I just tested now and the generated client can't be used within server routes. So based on this the Hey API docs should be recommending people put that file within
Suggested change
We only need to mention it within the docs in the runtime config section, and it doesn't need to be added to other examples imo. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What would need to change to make it work within server routes? Seems like an important issue, even if not directly related to this pull request There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree, it would make it so convenient for both building fully fullstack Nuxt, or BFFs (which are really popular with Nuxt). I believe the issue is because the client has imports for Nuxt and Vue things which can't be used on Nitro server routes. openapi-ts/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/bundle/client.ts Lines 1 to 7 in 91bc2d0
What I'd suggest is creating On top of this you could create a separate Nitro module for standalone Nitro users (since it's a fantastic backend framework) which acts similarly to the Nuxt module |
||||||||||||||||||||
}, | ||||||||||||||||||||
], | ||||||||||||||||||||
}, | ||||||||||||||||||||
}, | ||||||||||||||||||||
}); | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
```js [standalone] | ||||||||||||||||||||
export default { | ||||||||||||||||||||
input: 'hey-api/backend', // sign up at app.heyapi.dev | ||||||||||||||||||||
output: 'src/client', | ||||||||||||||||||||
plugins: [ | ||||||||||||||||||||
{ | ||||||||||||||||||||
name: '@hey-api/client-nuxt', | ||||||||||||||||||||
runtimeConfigPath: './src/hey-api.ts', // [!code ++] | ||||||||||||||||||||
runtimeConfigPath: './shared/lib/hey-api.ts', // [!code ++] | ||||||||||||||||||||
}, | ||||||||||||||||||||
], | ||||||||||||||||||||
}; | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
::: | ||||||||||||||||||||
|
||||||||||||||||||||
In our custom file, we need to export a `createClientConfig()` method. This function is a simple wrapper allowing us to override configuration values. | ||||||||||||||||||||
|
||||||||||||||||||||
::: code-group | ||||||||||||||||||||
|
||||||||||||||||||||
```ts [hey-api.ts] | ||||||||||||||||||||
import type { CreateClientConfig } from './client/client.gen'; | ||||||||||||||||||||
import type { CreateClientConfig } from '#hey-api/client.gen'; | ||||||||||||||||||||
|
||||||||||||||||||||
export const createClientConfig: CreateClientConfig = (config) => ({ | ||||||||||||||||||||
...config, | ||||||||||||||||||||
|
@@ -144,7 +227,7 @@ With this approach, `client.gen.ts` will call `createClientConfig()` before init | |||||||||||||||||||
You can also create your own client instance. You can use it to manually send requests or point it to a different domain. | ||||||||||||||||||||
|
||||||||||||||||||||
```js | ||||||||||||||||||||
import { createClient } from './client/client'; | ||||||||||||||||||||
import { createClient } from '#hey-api/client'; | ||||||||||||||||||||
|
||||||||||||||||||||
const myClient = createClient({ | ||||||||||||||||||||
baseURL: 'https://example.com', | ||||||||||||||||||||
|
@@ -180,7 +263,7 @@ If you omit `composable`, `$fetch` is used by default. | |||||||||||||||||||
::: | ||||||||||||||||||||
|
||||||||||||||||||||
```js | ||||||||||||||||||||
import { client } from 'client/client.gen'; | ||||||||||||||||||||
import { client } from '#hey-api/client.gen'; | ||||||||||||||||||||
|
||||||||||||||||||||
const result = await client.get({ | ||||||||||||||||||||
composable: '$fetch', | ||||||||||||||||||||
|
@@ -196,7 +279,7 @@ const result = await client.get({ | |||||||||||||||||||
The SDKs include auth mechanisms for every endpoint. You will want to configure the `auth` field to pass the right token for each request. The `auth` field can be a string or a function returning a string representing the token. The returned value will be attached only to requests that require auth. | ||||||||||||||||||||
|
||||||||||||||||||||
```js | ||||||||||||||||||||
import { client } from 'client/client.gen'; | ||||||||||||||||||||
import { client } from '#hey-api/client.gen'; | ||||||||||||||||||||
|
||||||||||||||||||||
client.setConfig({ | ||||||||||||||||||||
auth: () => '<my_token>', // [!code ++] | ||||||||||||||||||||
|
@@ -207,7 +290,7 @@ client.setConfig({ | |||||||||||||||||||
If you're not using SDKs or generating auth, using interceptors is a common approach to configuring auth for each request. | ||||||||||||||||||||
|
||||||||||||||||||||
```js | ||||||||||||||||||||
import { client } from 'client/client.gen'; | ||||||||||||||||||||
import { client } from '#hey-api/client.gen'; | ||||||||||||||||||||
|
||||||||||||||||||||
client.setConfig({ | ||||||||||||||||||||
onRequest: ({ options }) => { | ||||||||||||||||||||
|
@@ -248,7 +331,7 @@ console.log(url); // prints '/foo/1?bar=baz' | |||||||||||||||||||
You can implement your own `$fetch` method. This is useful if you need to extend the default `$fetch` method with extra functionality, or replace it altogether. | ||||||||||||||||||||
|
||||||||||||||||||||
```js | ||||||||||||||||||||
import { client } from 'client/client.gen'; | ||||||||||||||||||||
import { client } from '#hey-api/client.gen'; | ||||||||||||||||||||
|
||||||||||||||||||||
client.setConfig({ | ||||||||||||||||||||
$fetch: () => { | ||||||||||||||||||||
|
@@ -259,6 +342,31 @@ client.setConfig({ | |||||||||||||||||||
|
||||||||||||||||||||
You can use any of the approaches mentioned in [Configuration](#configuration), depending on how granular you want your custom method to be. | ||||||||||||||||||||
|
||||||||||||||||||||
## Standalone usage | ||||||||||||||||||||
|
||||||||||||||||||||
You can generate the Hey API Nuxt client via the CLI instead of the Nuxt module. | ||||||||||||||||||||
|
||||||||||||||||||||
In your [configuration](/openapi-ts/get-started), add `@hey-api/client-nuxt` to your plugins and you'll be ready to generate client artifacts. :tada: | ||||||||||||||||||||
|
||||||||||||||||||||
::: code-group | ||||||||||||||||||||
|
||||||||||||||||||||
```js [config] | ||||||||||||||||||||
export default { | ||||||||||||||||||||
input: 'hey-api/backend', // sign up at app.heyapi.dev | ||||||||||||||||||||
output: 'src/client', | ||||||||||||||||||||
plugins: ['@hey-api/client-nuxt'], // [!code ++] | ||||||||||||||||||||
}; | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
```sh [cli] | ||||||||||||||||||||
npx @hey-api/openapi-ts \ | ||||||||||||||||||||
-i hey-api/backend \ | ||||||||||||||||||||
-o src/client \ | ||||||||||||||||||||
-c @hey-api/client-nuxt # [!code ++] | ||||||||||||||||||||
``` | ||||||||||||||||||||
|
||||||||||||||||||||
::: | ||||||||||||||||||||
|
||||||||||||||||||||
## API | ||||||||||||||||||||
|
||||||||||||||||||||
You can view the complete list of options in the [UserConfig](https://github.com/hey-api/openapi-ts/blob/main/packages/openapi-ts/src/plugins/@hey-api/client-nuxt/types.d.ts) interface. | ||||||||||||||||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why make these changes? Once we finalize this page, we should have a v4 page too, it's ambiguous which version it's compatible with otherwise
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Going forwards a major Nuxt release should still be backwards compatible with older modules. When Nuxt v5 releases Q4 25/Q1 26 the same module should work without any new changes. Since Nuxt 2 is EOL I don't think there'll be any confusion about using the module with it.
https://nuxt.com/docs/4.x/guide/going-further/modules#do-not-advertise-with-a-specific-nuxt-version
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice work! I will still want to polish some of the wording in this copy, but overall I agree with the changes you've made/are making
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you 😄 docs isn't my strong suit