Skip to content

Commit 33a57a6

Browse files
committed
docs: Add Nuxt 3 example for openapi-fetch
1 parent d309753 commit 33a57a6

File tree

13 files changed

+5560
-159
lines changed

13 files changed

+5560
-159
lines changed

docs/openapi-fetch/examples.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,12 @@ _Note: if you’re using Svelte without SvelteKit, the root example in `src/rout
3434

3535
[View a code example in GitHub](https://github.com/openapi-ts/openapi-typescript/tree/main/packages/openapi-fetch/examples/vue-3)
3636

37+
## Nuxt 3
38+
39+
[Nuxt 3](https://nuxtjs.org/) is a popular SSR framework for Vue 3. By combining Nuxt's built-in [useAsyncData](https://nuxt.com/docs/api/composables/use-async-data) composable with openapi-fetch, you can easily implement type-safe API communication with server-side rendering. This example demonstrates how to fetch data during SSR and enable client-side refetching.
40+
41+
[View a code example in GitHub](https://github.com/openapi-ts/openapi-typescript/tree/main/packages/openapi-fetch/examples/nuxt-3)
42+
3743
---
3844

3945
Additional examples are always welcome! Please [open a PR](https://github.com/openapi-ts/openapi-typescript/pulls) with your examples.
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Nuxt dev/build outputs
2+
.output
3+
.data
4+
.nuxt
5+
.nitro
6+
.cache
7+
dist
8+
9+
# Node dependencies
10+
node_modules
11+
12+
# Logs
13+
logs
14+
*.log
15+
16+
# Misc
17+
.DS_Store
18+
.fleet
19+
.idea
20+
21+
# Local env files
22+
.env
23+
.env.*
24+
!.env.example
Lines changed: 168 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,168 @@
1+
<script setup>
2+
import { useAsyncData } from '#app';
3+
import client from "@/lib/api";
4+
5+
// ssr fetching example
6+
const { data: catFact, error, pending, refresh } = useAsyncData(
7+
'catFact',
8+
async () => {
9+
const { data, error } = await client.GET("/fact", {
10+
params: {
11+
query: {
12+
max_length: 140,
13+
},
14+
},
15+
});
16+
17+
if (error) {
18+
throw error;
19+
}
20+
return data;
21+
}
22+
);
23+
24+
const isRefetching = ref(false);
25+
26+
async function fetchNewFact() {
27+
isRefetching.value = true;
28+
await refresh();
29+
isRefetching.value = false;
30+
}
31+
</script>
32+
33+
<template>
34+
<div class="cat-fact-container">
35+
<h1 class="title">Cat Facts</h1>
36+
37+
<div v-if="pending || isRefetching" class="loading">
38+
<span class="loader"></span> Loading...
39+
</div>
40+
41+
<div v-else-if="error" class="error">
42+
<p>{{ error.message }}</p>
43+
<p class="error-code">Error code: {{ error.code }}</p>
44+
</div>
45+
46+
<div v-else-if="catFact" class="fact-card">
47+
<p class="fact">{{ catFact.fact }}</p>
48+
<span class="fact-length">Character count: {{ catFact.length }}</span>
49+
</div>
50+
51+
<button @click="fetchNewFact" class="fetch-button" :disabled="pending || isRefetching">
52+
{{ (pending || isRefetching) ? 'Fetching...' : 'Get New Cat Fact' }}
53+
</button>
54+
</div>
55+
</template>
56+
57+
<style>
58+
:root {
59+
--color-primary: #00DC82;
60+
--color-primary-dark: #00C476;
61+
--color-primary-light: #94E3C9;
62+
--color-secondary: #F3F4F6;
63+
--color-text: #374151;
64+
--color-text-light: #666666;
65+
--color-error: #EF4444;
66+
--color-error-bg: #FEE2E2;
67+
--color-background: #F9FAFB;
68+
}
69+
</style>
70+
71+
<style scoped>
72+
.cat-fact-container {
73+
max-width: 600px;
74+
margin: 0 auto;
75+
padding: 2rem;
76+
font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
77+
color: var(--color-text);
78+
}
79+
80+
.title {
81+
font-size: 2rem;
82+
margin-bottom: 2rem;
83+
color: var(--color-primary);
84+
text-align: center;
85+
}
86+
87+
.loading {
88+
display: flex;
89+
align-items: center;
90+
justify-content: center;
91+
margin: 2rem 0;
92+
color: var(--color-text-light);
93+
}
94+
95+
.loader {
96+
display: inline-block;
97+
width: 1rem;
98+
height: 1rem;
99+
margin-right: 0.5rem;
100+
border: 2px solid var(--color-primary);
101+
border-radius: 50%;
102+
border-top-color: transparent;
103+
animation: spin 1s linear infinite;
104+
}
105+
106+
@keyframes spin {
107+
to {
108+
transform: rotate(360deg);
109+
}
110+
}
111+
112+
.error {
113+
background-color: var(--color-error-bg);
114+
color: var(--color-error);
115+
padding: 1rem;
116+
border-radius: 0.5rem;
117+
margin: 2rem 0;
118+
}
119+
120+
.error-code {
121+
font-size: 0.875rem;
122+
opacity: 0.8;
123+
}
124+
125+
.fact-card {
126+
background-color: var(--color-secondary);
127+
padding: 1.5rem;
128+
border-radius: 0.5rem;
129+
box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);
130+
margin: 2rem 0;
131+
}
132+
133+
.fact {
134+
font-size: 1.25rem;
135+
line-height: 1.6;
136+
margin-bottom: 1rem;
137+
}
138+
139+
.fact-length {
140+
display: block;
141+
text-align: right;
142+
font-size: 0.875rem;
143+
color: var(--color-text-light);
144+
}
145+
146+
.fetch-button {
147+
display: block;
148+
width: 100%;
149+
padding: 0.75rem 1rem;
150+
background-color: var(--color-primary);
151+
color: white;
152+
border: none;
153+
border-radius: 0.5rem;
154+
font-size: 1rem;
155+
font-weight: 600;
156+
cursor: pointer;
157+
transition: background-color 0.2s;
158+
}
159+
160+
.fetch-button:hover {
161+
background-color: var(--color-primary-dark);
162+
}
163+
164+
.fetch-button:disabled {
165+
background-color: var(--color-primary-light);
166+
cursor: not-allowed;
167+
}
168+
</style>
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# openapi-fetch + Nuxt3
2+
3+
Example of using openapi-fetch with [Nuxt3](https://nuxt.com/).
4+
5+
## Setup
6+
7+
```sh
8+
pnpm i
9+
pnpm run dev
10+
```
11+
12+
You’ll see the server running at `localhost:3000`
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import type { paths } from "@/lib/api/v1";
2+
import createClient from "openapi-fetch";
3+
4+
const client = createClient<paths>({ baseUrl: "https://catfact.ninja/" });
5+
6+
export default client;

0 commit comments

Comments
 (0)