@@ -25,7 +25,7 @@ You can find the code for this project in this
2525
2626## Scaffold a Nuxt app with Deno
2727
28- We can create a new Nuxt project using deno like this:
28+ We can create a new Nuxt project using Deno like this:
2929
3030``` bash
3131deno -A npm:nuxi@latest init
@@ -60,9 +60,7 @@ First, our
6060[ dinosaur data] ( https://github.com/denoland/examples/blob/main/with-nuxt/server/api/data.json )
6161will live within the server directory as ` server/api/data.json ` :
6262
63- ``` json
64- // server/api/data.json
65-
63+ ``` json title="server/api/data.json"
6664[
6765 {
6866 "name" : " Aardonyx" ,
@@ -76,7 +74,7 @@ will live within the server directory as `server/api/data.json`:
7674 "name" : " Abrictosaurus" ,
7775 "description" : " An early relative of Heterodontosaurus."
7876 },
79- ...
77+ ...etc
8078]
8179```
8280
@@ -87,35 +85,21 @@ would come from a database.
8785> to [ a variety of databases] ( https://docs.deno.com/runtime/tutorials/connecting_to_databases/ ) and [ even use ORMs like Prisma] ( https://docs.deno.com/runtime/tutorials/how_to_with_npm/prisma/ ) with
8886> Deno.
8987
90- Next, let’s add type definitions for our dinosaur data. We’ll put it in a new
91- folder, ` types ` :
92-
93- ``` tsx
94- // types/index.ts
95-
96- export interface Dino {
97- name: string ;
98- description: string ;
99- }
100- ```
101-
102- We’ll create two API routes to serve the following:
88+ This app will have two API routes. They will serve the following:
10389
10490- the full list of dinosaurs for an index page
10591- individual dinosaur information for an individual dinosaur page
10692
10793Both will be ` *.get.ts ` files, which Nuxt automatically converts to API
108- endpoints to respond to GET requests.
94+ endpoints to respond to ` GET ` requests.
10995[ The filename convention determines both the HTTP method and the route path] ( https://nuxt.com/docs/guide/directory-structure/server#matching-http-method ) .
11096
11197The initial ` dinosaurs.get.ts ` is fairly simple and uses
11298[ ` defineCachedEventHandler ` ] ( https://nitro.build/guide/cache ) to create a cached
11399endpoint for better performance. This handler simply returns our full dinosaur
114100data array without any filtering:
115101
116- ``` tsx
117- // server/api/dinosaurs.get.ts
118-
102+ ``` tsx title="server/api/dinosaurs.get.ts"
119103import data from " ./data.json" with { type: " json" };
120104
121105export default defineCachedEventHandler (() => {
@@ -126,12 +110,10 @@ export default defineCachedEventHandler(() => {
126110The ` GET ` route for the individual dinosaur has a little more logic. It extracts
127111the name parameter from the event context, performs case-insensitive matching to
128112find the requested dinosaur, and includes proper error handling for missing or
129- invalid dinosaur names. To pass the name parameter, let’s name this route as
130- ` [name].get.ts ` :
131-
132- ``` tsx
133- // server/api/dinosaurs/[name].get.ts
113+ invalid dinosaur names. We'll create a ` dinosaurs ` directory, then to pass the
114+ name parameter, we'll make a new file named ` [name].get.ts ` :
134115
116+ ``` tsx title="server/api/dinosaurs/[name].get.ts"
135117import data from " ../data.json" ;
136118
137119export default defineCachedEventHandler ((event ) => {
@@ -159,37 +141,38 @@ export default defineCachedEventHandler((event) => {
159141});
160142```
161143
162- Awesome. When we run the server with ` deno task dev ` and point our browser to
163- ` localhost:3000/api/dinosaurs ` , we can see the raw JSON response showing all of
164- the dinosaurs:
144+ Run the server with ` deno task dev ` and visit
145+ [ http:// localhost:3000/api/dinosaurs] ( http://localhost:3000/api/dinosaurs ) in
146+ your browser, you should see the raw JSON response showing all of the dinosaurs!
165147
166148![ Setting up API] ( ./images/how-to/nuxt/nuxt-1.webp )
167149
168- You can also retrieve data for a single dinosaur by going to
169- ` localhost:3000/api/dinosaurs/aardonyx ` .
150+ You can also retrieve data for a single dinosaur by visiting a particular
151+ dinosaur name, for example:
152+ [ http://localhost:3000/api/dinosaurs/aardonyx ] ( http://localhost:3000/api/dinosaurs/aardonyx ) .
170153
171154![ Setting up API] ( ./images/how-to/nuxt/nuxt-2.webp )
172155
173- Next, let’s setup the frontend with Vue to display the index page and each
156+ Next, we'll setup the frontend with Vue to display the index page and each
174157individual dinosaur page.
175158
176- ## Setup Vue frontend
159+ ## Setup the Vue frontend
177160
178- We want to set up two pages within our app:
161+ We want to set up two pages within the app:
179162
180- - An index page which will list all our dinosaurs
181- - An individual dinosaur page showing more information about our selected
163+ - An index page which will list all of the dinosaurs
164+ - An individual dinosaur page showing more information about the selected
182165 dinosaur.
183166
184- Let’s first create the index page. Since Nuxt uses
185- [ file-system routing] ( https://nuxt.com/docs/getting-started/routing ) , let’s
186- create a ` pages ` directory and within that, our index page at ` pages/index.vue ` .
167+ First, create the index page. Nuxt uses
168+ [ file-system routing] ( https://nuxt.com/docs/getting-started/routing ) , so we will
169+ create a ` pages ` directory in the root, and within that an index page called
170+ ` index.vue ` .
171+
187172To get the data, we’ll use the ` useFetch ` composable to hit the API endpoint we
188173created in the previous section:
189174
190- ``` tsx
191- // pages/index.vue
192-
175+ ``` tsx title="pages/index.vue"
193176<script setup lang = " ts" >
194177const { data : dinosaurs } = await useFetch("/api/dinosaurs");
195178</script >
@@ -212,17 +195,15 @@ const { data: dinosaurs } = await useFetch("/api/dinosaurs");
212195< / template >
213196```
214197
215- For our next page that shows information for each dinosaur, let’s create a
216- dynamic page: ` pages/ [name].vue` . This page uses Nuxt's
198+ For the page that shows information on each dinosaur, we'll create a new dynamic
199+ page called ` [name].vue ` . This page uses Nuxt's
217200[ dynamic route parameters] ( https://nuxt.com/docs/getting-started/routing#route-parameters ) ,
218201where the ` [name] ` in the filename can be accessed in JavaScript as
219202` route.params.name ` . We’ll use the ` useRoute ` composable to access the route
220203parameters and ` useFetch ` to get the specific dinosaur's data based on the name
221204parameter:
222205
223- ``` tsx
224- // pages/[name].vue
225-
206+ ``` tsx title="pages/[name].vue"
226207<script setup lang = " ts" >
227208const route = useRoute();
228209const { data : dinosaur } = await useFetch(
@@ -248,9 +229,7 @@ root of the directory to serve our application’s root component. We’ll use
248229page structure and [ ` NuxtPage ` ] ( https://nuxt.com/docs/api/components/nuxt-page )
249230for dynamic page rendering:
250231
251- ``` tsx
252- // app.vue
253-
232+ ``` tsx title="app.vue"
254233<template >
255234 <NuxtLayout >
256235 <div >
@@ -268,8 +247,8 @@ for dynamic page rendering:
268247</template >;
269248```
270249
271- Let’s run our server with ` deno task dev ` and see how it looks at
272- ` localhost:3000 ` :
250+ Run the server with ` deno task dev ` and see how it looks at
251+ [ http:// localhost:3000] ( http://localhost:3000 ) :
273252
274253<figure >
275254
@@ -286,9 +265,7 @@ First, we'll set up a layout which will provide a consistent structure across
286265all pages using Nuxt's layout system with
287266[ slot-based] ( https://vuejs.org/guide/components/slots ) content injection:
288267
289- ``` tsx
290- // layouts/default.vue
291-
268+ ``` tsx title="layouts/default.vue"
292269<template >
293270 <div >
294271 <slot />
@@ -303,48 +280,15 @@ for some basic design, so we need to install those dependencies:
303280deno install -D npm:tailwindcss npm:@tailwindcss/vite
304281```
305282
306- Then, we're going to update our ` nuxt.config.ts ` file by adding the
307- ` @tailwindcss/vite ` plugin to our Nuxt configuration as a Vite plugin.
308-
309- ``` tsx
310- // nuxt.config.ts
311-
312- import tailwindcss from " @tailwindcss/vite" ;
313-
314- export default defineNuxtConfig ({
315- compatbilityDate: " 2025-05-15" ,
316- devtools: { enabled: true },
317- vite: {
318- plugins: [
319- tailwindcss (),
320- ],
321- },
322- });
323- ```
324-
325- Next, let’s create a new css file, ` assets/css/main.css ` , and add an import
326- ` @import ` that imports tailwind, as well as the tailwind utilities.
327-
328- ``` tsx
329- // assets/css/main.css
330- @import " tailwindcss" ;
331-
332- @tailwind base ;
333- @tailwind components ;
334- @tailwind utilities ;
335- ```
336-
337- The only other thing we'll need to do is update our ` nuxt.config.ts ` file to
338- configure our Nuxt application for Deno compatibility, enable development tools,
339- and set up Tailwind CSS.
340-
341- ``` tsx
342- // nuxt.config.ts
283+ Then, we're going to update the ` nuxt.config.ts ` . Import the Tailwind dependency
284+ and configure the Nuxt application for Deno compatibility, We'll enable
285+ development tools, and set up Tailwind CSS:
343286
287+ ``` tsx title="nuxt.config.ts"
344288import tailwindcss from " @tailwindcss/vite" ;
345289
346290export default defineNuxtConfig ({
347- compatbilityDate : " 2025-05-15" ,
291+ compatibilityDate : " 2025-05-15" ,
348292 devtools: { enabled: true },
349293 nitro: {
350294 preset: " deno" ,
@@ -363,9 +307,20 @@ export default defineNuxtConfig({
363307});
364308```
365309
366- ## Running Our Application
310+ Next, create a new css file, ` assets/css/main.css ` , and add an import ` @import `
311+ that imports tailwind, as well as the tailwind utilities:
367312
368- We can then run our application using:
313+ ``` tsx title="assets/css/main.css"
314+ @import " tailwindcss" ;
315+
316+ @tailwind base ;
317+ @tailwind components ;
318+ @tailwind utilities ;
319+ ```
320+
321+ ## Running the application
322+
323+ We can then run the application using:
369324
370325``` bash
371326deno task dev
@@ -381,9 +336,7 @@ This will start the app at localhost:3000:
381336
382337And we’re done!
383338
384- ## Next steps
385-
386- Next steps for a Nuxt app might be to add authentication using the
339+ 🦕 Next steps for a Nuxt app might be to add authentication using the
387340[ Nuxt Auth] ( https://auth.nuxtjs.org/ ) module, implement state management with
388341[ Pinia] ( https://pinia.vuejs.org/ ) , add server-side data persistence with
389342[ Prisma] ( https://docs.deno.com/examples/prisma_tutorial/ ) or
0 commit comments