Movatterモバイル変換


[0]ホーム

URL:


Skip to main content
⌘K
Up or down tonavigateEnter toselectEscape toclose
On this page

Build a Nuxt app with Deno

Nuxt is a framework that provides an intuitive way tocreate full-stack applications based onVue. It offersfile-based routing, a variety of rendering options, and automatic code splittingout of the box. With its modular architecture, Nuxt simplifies the developmentprocess by providing a structured approach to building Vue applications.

In this tutorial, we'll build a simple Nuxt application with Deno that willdisplay a list of dinosaurs and allow you to learn more about each one when youclick on the name.

You can see thefinished app on GitHub.

You can see alive version of the app on Deno Deploy.

Deploy your own

Want to skip the tutorial and deploy the finished app right now? Click thebutton below to instantly deploy your own copy of the complete Nuxt dinosaur appto Deno Deploy. You'll get a live, working application that you can customizeand modify as you learn!

Deploy on Deno

Scaffold a Nuxt app with DenoJump to heading

We can create a new Nuxt project using Deno like this:

deno-A npm:nuxi@latest init

Select the directory where you want to create the project, and choosedeno tomanage dependencies. You can also choose to initialize a git repository if youwant, or we can do that later.

Next change directory into the newly created project, you can check which tasksNuxt has available by runningdeno task.

cd nuxt-appdeno task

This will show you the available tasks, such asdev,build, andpreview.Thedev task is used to start the development server.

Start the development serverJump to heading

Now we can start the development server with:

deno task dev

This will start the Nuxt development server, and you can visithttp://localhost:3000 in your browser to see thedefault Nuxt welcome page.

Build out the app architectureJump to heading

Now that we have a basic Nuxt app set up, we can start building out theapplication architecture. We'll create a few directories to organize our codeand prepare for the features we want to implement. Create the followingdirectories in your project:

NUXT-APP/├── pages/# Vue pages│   └── dinosaurs/# Dinosaur pages├── public/# Static files├── server/# Server-side code│   └── api/# API routes

Add dinosaur dataJump to heading

In theapi directory, create a new file calleddata.json file, which willcontain the hard coded dinosaur data.

Copy and pastethis json fileinto thedata.json file. (If you were building a real app, you would probablyfetch this data from a database or an external API.)

Setup the API routesJump to heading

This app will have two API routes. They will serve the following:

  • the full list of dinosaurs for an index page
  • individual dinosaur information for an individual dinosaur page

Both will be*.get.ts files, which Nuxt automatically converts to APIendpoints to respond toGET requests.The filename convention determines both the HTTP method and the route path.

The initialdinosaurs.get.ts is fairly simple and usesdefineCachedEventHandler to create a cachedendpoint for better performance. This handler simply returns our full dinosaurdata array without any filtering:

server/api/dinosaurs.get.ts
import datafrom"./data.json"with{ type:"json"};exportdefaultdefineCachedEventHandler(()=>{return data;});

TheGET route for the individual dinosaur has a little more logic. It extractsthe name parameter from the event context, performs case-insensitive matching tofind the requested dinosaur, and includes proper error handling for missing orinvalid dinosaur names. We'll create adinosaurs directory, then to pass thename parameter, we'll make a new file named[name].get.ts:

server/api/dinosaurs/[name].get.ts
import datafrom"../data.json";exportdefaultdefineCachedEventHandler((event)=>{const name=getRouterParam(event,"name");if(!name){throwcreateError({      statusCode:400,      message:"No dinosaur name provided",});}const dinosaur= data.find((dino)=> dino.name.toLowerCase()=== name.toLowerCase(),);if(!dinosaur){throwcreateError({      statusCode:404,      message:"Dinosaur not found",});}return dinosaur;});

Run the server withdeno task dev and visithttp://localhost:3000/api/dinosaurs inyour browser, you should see the raw JSON response showing all of the dinosaurs!

Setting up API

You can also retrieve data for a single dinosaur by visiting a particulardinosaur name, for example:http://localhost:3000/api/dinosaurs/aardonyx.

Setting up API

Next, we'll setup the frontend with Vue to display the index page and eachindividual dinosaur page.

Setup the Vue frontendJump to heading

We want to set up two pages within the app:

  • An index page which will list all of the dinosaurs
  • An individual dinosaur page showing more information about the selecteddinosaur.

First, create the index page. Nuxt usesfile-system routing, so we willcreate apages directory in the root, and within that an index page calledindex.vue.

To get the data, we’ll use theuseFetch composable to hit the API endpoint wecreated in the previous section:

pages/index.vue
<scriptsetuplang="ts">const { data: dinosaurs } = await useFetch("/api/dinosaurs");</script><template><mainid="content"><h1class="text-2xl font-bold mb-4">Welcome to the Dinosaur app</h1><pclass="mb-4">Click on a dinosaur below to learn more.</p><ulclass="space-y-2"><liv-for="dinosaur in dinosaurs":key="dinosaur.name"><NuxtLink:to="'/' + dinosaur.name.toLowerCase()"class="text-blue-600 hover:text-blue-800 hover:underline">{{ dinosaur.name}}</NuxtLink></li></ul></main></template>

For the page that shows information on each dinosaur, we'll create a new dynamicpage called[name].vue. This page uses Nuxt'sdynamic route parameters,where the[name] in the filename can be accessed in JavaScript asroute.params.name. We’ll use theuseRoute composable to access the routeparameters anduseFetch to get the specific dinosaur's data based on the nameparameter:

pages/[name].vue
<scriptsetuplang="ts">const route = useRoute();const { data: dinosaur } = await useFetch(  `/api/dinosaurs/${route.params.name}`);</script><template><mainv-if="dinosaur"><h1class="text-2xl font-bold mb-4">{{ dinosaur.name}}</h1><pclass="mb-4">{{ dinosaur.description}}</p><NuxtLinkto="/"class="text-blue-600 hover:text-blue-800 hover:underline">      Back to all dinosaurs</NuxtLink></main></template>

Next, we’ll have to connect these Vue components together so that they renderproperly when we visit the root of the domain. Let’s updateapp.vue at theroot of the directory to serve our application’s root component. We’ll useNuxtLayout for consistentpage structure andNuxtPagefor dynamic page rendering:

app.vue
<template><NuxtLayout><div><navclass="p-4 bg-gray-100"><NuxtLinkto="/"class="text-blue-600 hover:text-blue-800">          Dinosaur Encyclopedia</NuxtLink></nav><divclass="container mx-auto p-4"><NuxtPage/></div></div></NuxtLayout></template>;

Run the server withdeno task dev and see how it looks athttp://localhost:3000:

Looks great!

denoinstall-D npm:tailwindcss npm:@tailwindcss/vite

Then, we're going to update thenuxt.config.ts. Import the Tailwind dependencyand configure the Nuxt application for Deno compatibility, We'll enabledevelopment tools, and set up Tailwind CSS:

nuxt.config.ts
import tailwindcssfrom"@tailwindcss/vite";exportdefaultdefineNuxtConfig({  compatibilityDate:"2025-05-15",  devtools:{ enabled:true},  nitro:{    preset:"deno",},  app:{    head:{      title:"Dinosaur Encyclopedia",},},  css:["~/assets/css/main.css"],  vite:{    plugins:[tailwindcss(),],},});

Next, create a new css file,assets/css/main.css, and add an import@importthat imports tailwind, as well as the tailwind utilities:

assets/css/main.css
@import"tailwindcss";@tailwind base;@tailwind components;@tailwind utilities;

Running the applicationJump to heading

We can then run the application using:

deno task dev

This will start the app at localhost:3000:

And we’re done!

🦕 Next steps for a Nuxt app might be to add authentication using theNuxt Auth module, implement state management withPinia, add server-side data persistence withPrisma orMongoDB, and set upautomated testing with Vitest. These features would make it production-ready forlarger applications.

Did you find what you needed?

What can we do to improve this page?

If provided, you'll be @mentioned in the created GitHub issue

Privacy policy

[8]ページ先頭

©2009-2025 Movatter.jp