Skip to content

Announcing Our New Starter.dev Kit: Nuxt 3 with Pinia and Vuetify

This article was written over 18 months ago and may contain information that is out of date. Some content may be relevant but please refer to the relevant official documentation or available resources for the latest information.

We're thrilled to unveil our brand new starter.dev kit: a Nuxt 3 kit using Pinia as the state manager and Vuetify for styles.

While Nuxt 2 is still reliable and powerful, Nuxt 3, being the latest iteration of this versatile framework, brings an array of innovative features and enhanced flexibility that make it an ideal choice for your next development project.

Now, let's explore what this kit offers, and how it can help you in your upcoming application development.

Nuxt 3 vs Nuxt 2

First, why Nuxt 3? Let's delve into what Nuxt 3 is and why we've opted for this technology for our kit.

Nuxt 3 is a modern web development framework based on Vue 3 for building server-side rendered applications, single-page applications, or statically rendered websites. It's an evolution of Nuxt 2 and provides an improved developer experience and better performance.

Let’s see what features it has to offer in comparison to Nuxt 2!

  • Built on Vue 3: Nuxt 3 is built from the ground up using Vue 3, which brings a host of new features including conditional suspending of component rendering via the Suspense API, more flexibility for global mounting, and a Virtual DOM rewrite for better performance and improved TypeScript support.

  • Nitro Engine: Nitro, the new rendering server for Nuxt 3, is built for serverless architectures and offers extremely fast cold-start times. Nuxt 3 is planned to support Incremental Static Regeneration (ISR) using the Nitro renderer.

  • Native Composition API Support: Nuxt 3 has native support for the Vue Composition API, a feature that Nuxt 2 had to rely on an external library to use. The Composition API changes how code is written in Vue and is now built-in with Nuxt 3 since it is built on top of Vue 3.

  • Faster Hot Reloads with Vite: Nuxt 3 uses Vite for Hot Module Replacement (HMR), which is used when the server re-renders the updated components of your application in both development and production. This leads to faster hot reloads.

  • Additional Features: There are several other salient features of Nuxt 3, including a new Nuxt CLI (nuxi), NuxtJS Dev tools, and global auto imports of common functions such as ref​.

Nuxt 3 brings remarkable performance enhancements, significantly reducing the size of server deployments and client bundles. These improvements are made possible by implementing a new renderer, faster hot reloads, and built-in support for native TypeScript and Composition API, as mentioned earlier. With such impressive features at our disposal, the decision to choose this framework was undoubtedly the right one.

###Pinia

Let's talk about the state management library we've chosen. As the successor to Vuex, Pinia is now the default state management library for Vue 3.

Pinia shines when sharing global state within your application; it ensures security and ease of use, especially when using SSR, which is often the case with Nuxt.

Pinia's integration with Nuxt 3 is seamless, benefiting from Vue 3's inbuilt Composition API. The use of Pinia greatly simplifies the state management in Vue-based applications.

###Vuetify

Vuetify is an exceptional Material Design framework for Vue.js that assists in building elegant, responsive, and interactive web applications.

In Nuxt 3, the integration of Vuetify can be done smoothly, thanks to Nuxt's flexibility. This makes the process of building modern, visually appealing applications more efficient and enjoyable.

What's inside the Nuxt 3 Kit?

Our aim in developing the starter.dev kit is to equip you with essentials while maintaining flexibility.

The kit incorporates a counter component that manages state using a Pinia store, and a Fetch component showcasing data fetch in Nuxt 3. We decided to omit Storybook and testing from this starter.dev kit. Storybook is currently incompatible with Nuxt 3, but rest assured, we will incorporate it as soon as compatibility support is introduced.

Regarding testing, tools like Vitest and others have been excluded for now. The current Nuxt 3 testing landscape is still under development and not deemed production-ready. As the testing environment matures, we will update our starter.dev kit to include the most efficient and reliable testing solutions.

Furthermore, the kit includes configurations for ESLint, Prettier, and is written entirely in TypeScript. This saves you significant time by taking the hassle out of setting up these tools in a new project.

How do I use the kit?

Use our starter.dev CLI! This is by far the easiest method.

Simply run the command

npx @this-dot/create-starter

This will display a list of available starter.dev kits. Select the one that fits your needs - in this case, the nuxt3-pinia-vuetify one! You'll be asked to provide a name for your new project, and once that's inputted, the CLI will begin preparing the kit for you!

Once installed, you can cd into your new project directory with the name you provided earlier, and start coding. But don’t forget to install the required dependencies with your package manager of choice (I recommend pnpm 🫣).

For a deeper insight into the kit, visit https://starter.dev/kits/nuxt3-pinia-vuetify/ where you can read the README.md file for more detailed documentation, as well as take a look at the source code. Don't forget to read the package.json file to see the scripts available for the kit.

Conclusion

In a nutshell, our new starter.dev kit integrates Nuxt 3, Pinia, and Vuetify.. This article not only introduces you to the kit but also delves into the features and advantages that make it stand out - the improved performance of Nuxt 3, the ease of state management with Pinia, and the sophisticated stylings of Vuetify. As the digital landscape evolves, we will keep this kit updated with tools like Storybook and comprehensive testing capabilities as soon as they become Nuxt 3-compatible.

That's it, folks! We're eager for you to take this kit for a spin in your next project. We've built it with much care and attention to detail, ensuring it brings significant value to your development process. We hope you find it as enjoyable to use as we did creating it. Happy coding!

This Dot is a consultancy dedicated to guiding companies through their modernization and digital transformation journeys. Specializing in replatforming, modernizing, and launching new initiatives, we stand out by taking true ownership of your engineering projects.

We love helping teams with projects that have missed their deadlines or helping keep your strategic digital initiatives on course. Check out our case studies and our clients that trust us with their engineering.

You might also like

Rendering Modes in Nuxt 3 cover image

Rendering Modes in Nuxt 3

Nuxt is an open source framework to make your Vue.js applications. Currently, Nuxt 3 has a release candidate and the stable version would be out soon. In this series, I would be taking us through Nuxt 3 concepts and APIs. In this first part, we would focus on rendering modes in Nuxt 3. Setup To quickly install Nuxt 3, lets use the nuxt 3 documentation. Rendering modes Nuxt 3 offers a couple of different rendering modes: - Universal Rendering - Client-side rendering - Hybrid rendering Each of this rendering modes have their use cases and benefits. In this article, we will take a look at their pros, and how to implement them in Nuxt 3. Universal Rendering Universal rendering allows for code to be pre-rendered at build time or rendered on the server before it is served to the client on request. This results in very fast pages, because rendering on the server is faster and the user gets content on page load compared to Client-Side only rendering. Nuxt 3 also improves this greatly by allowing code to be rendered not just on node-js servers, but also on CDN edge workers. This increases the site speed, and also helps reduces cost. In Universal rendering, we can use pre-rendering. This means we can have some pages, or all pages, pre-rendered on build time, and other pages rendered at request time. This is a great choice for static pages like website landing pages, blogs and some dynamic pages that don’t change often and have a finite number of pages. Universal mode with server side rendering is best for sites with highly dynamic content that changes frequently, like ecommerce sites. Pros Search Engine Optimization: Universal rendered apps serve the page with the generated html content to the browser. This makes it easy for web crawlers to index such pages. Performance: The performance of Universal rendered apps are fast compared to Client-side rendered apps because the page already contains the HTML code, and this does not rely on the users device to parse and render the HTML. To deploy and use our Nuxt 3 application on a node-server in universal mode: First in nuxt.config.js file ` By default, SSR is set to true if it is not passed in the nuxt.config.js file. Also, preset is set to ‘node-server’ by default, but this can be changed to suit the deployment environment. For example, Vercel preset should be used for Vercel deployment. You can read here for available deployment presets. When we run our build command: ` This will generate the output folder with the app's entry point file. Next, we can run the file with Node. ` or ` To deploy and use our Nuxt 3 application on a static server in universal mode: First, in our nuxt.config.js file, we specify the pages to be generated: ` Now we can run our generate command: ` This will generate the output folder '.output/public' with the pages files and the related JS and CSS files. We can simply place this folder into any static hosting service, and access our application. To generate our routes async, like a blog website, we can fetch our routes and then pass it to the route during build with this hook. ` Client side rendering Client side rendering involves sending every request to a single file, usually ‘index.html’, with empty content and then linking them to the corresponding JS bundles, allowing the browser perform the parsing and rendering of the HTML. Client side rendering is a great choice for heavily interactive websites with animations, like online gaming sites, Saas sites, etc. Pros Offline support: Client-side rendered apps can run offline once the dependent JavaScript files are downloaded if there is no internet. It is easy to make a client side rendered app a Progressive web app. Cheap: Client-side rendered apps are the cheapest in terms of hosting as you do not need to run a server. They are made up of HTML and JS files which can be served from a static server. To config our Nuxt 3 app to be fully client side rendered: First in nuxt.config.js file ` Now we can run our generate command: ` This will generate the output folder '.output/public/index.html' with the apps entry point file and the related js files. We can simply place this folder onto any static hosting service, and access our application. Hybrid rendering Hybrid rendering is an unreleased Nuxt 3 feature that allows developers to configure different rendering modes for different pages. This should be available later this year, and we will explore it in this series once it is. For more official information about the hybrid rendering discussion. In the next article, we will implement a simple webpage using the universal rendering. The webpage will have a blog which will be prerendered, and also a dynamic user page which will be server rendered. --- I hope this article has been helpful to you. If you encounter any issues, you can reach out to me on Twitter or Github....

How to Style Using SCSS in Nuxt cover image

How to Style Using SCSS in Nuxt

Introduction SASS makes working on large projects more organized. It allows you to use variables, nested rules, mixins, and functions. The preferred styling method in Nuxt is component file styling, and integrating SASS into your project can make your component file styling appear more understandable. How to Import SASS in Nuxt To add SASS after setting up your Nuxt application, we will first install SASS and sass-loader. Let's run either of these commands depending on our package manager. ` Component File Styling With SASS and sass-loader installed in our project, we can now write SCSS in our component file. Lets see an example: ` In the example above, all we need to specify is lang="scss" on the style tag, and we can now write scss in that component. Global File Import and Variables To import SCSS files that are global, like variables and mixins files, we need to install style-resources: ` Next, we can update our nuxt.config.js file by adding the module we just installed to the buildModules. ` Next, let's create a global variables.scss file in our assets/style folder. Add a single variable inside: ` Next, we need to import this file inside the nuxt.config file: ` Now we have the variables in our variables.scss available in all our components for use. Next, let's test it out by updating our button component. ` We have updated our button variant color to be our global SCSS variable ($primary and $white). Mixins Mixins in SASS are used to write styles that can be reused in other parts of the code. Let's create a sample mixin to center an item. ` Next, we need to import our mixin in Nuxt config: ` Now, let's update our button component with our mixin: ` Functions Functions in SASS are used to write complex operations or behaviours that can be reused in other parts of the code. Let's create a function to handle a media query for our application. ` This is a basic example of what a function can be used for. More complex cases, like calculating percentage, can also be done. Let's import our mixin in Nuxt config: ` Let's update our button component with our function: ` We have been able to add SASS to our Nuxt project, and also looked at some ways in which SASS can make our codebase look cleaner. I hope this article has been helpful to you. If you encounter any issues, you can reach out to me on Twitter or Github....

How to build an AI assistant with OpenAI, Vercel AI SDK, and Ollama with Next.js cover image

How to build an AI assistant with OpenAI, Vercel AI SDK, and Ollama with Next.js

In today’s blog post, we’ll build an AI Assistant using three different AI models: Whisper and TTS from OpenAI and Llama 3.1 from Meta. While exploring AI, I wanted to try different things and create an AI assistant that works by voice. This curiosity led me to combine OpenAI’s Whisper and TTS models with Meta’s Llama 3.1 to build a voice-activated assistant. Here’s how these models will work together: * First, we’ll send our audio to the Whisper model, which will convert it from speech to text. * Next, we’ll pass that text to the Llama 3.1 model. Llama will understand the text and generate a response. * Finally, we’ll take Llama’s response and send it to the TTS model, turning the text back into speech. We’ll then stream that audio back to the client. Let’s dive in and start building this excellent AI Assistant! Getting started We will use different tools to build our assistant. To build our client side, we will use Next.js. However, you could choose whichever framework you prefer. To use our OpenAI models, we will use their TypeScript / JavaScript SDK. To use this API, we require the following environmental variable: OPENAI_API_KEY— To get this key, we need to log in to the OpenAI dashboard and find the API keys section. Here, we can generate a new key. Awesome. Now, to use our Llama 3.1 model, we will use Ollama and the Vercel AI SDK, utilizing a provider called ollama-ai-provider. Ollama will allow us to download our preferred model (we could even use a different one, like Phi) and run it locally. The Vercel SDK will facilitate its use in our Next.js project. To use Ollama, we just need to download it and choose our preferred model. For this blog post, we are going to select Llama 3.1. After installing Ollama, we can verify if it is working by opening our terminal and writing the following command: Notice that I wrote “llama3.1” because that’s my chosen model, but you should use the one you downloaded. Kicking things off It's time to kick things off by setting up our Next.js app. Let's start with this command: ` After running the command, you’ll see a few prompts to set the app's details. Let's go step by step: * Name your app. * Enable app router. The other steps are optional and entirely up to you. In my case, I also chose to use TypeScript and Tailwind CSS. Now that’s done, let’s go into our project and install the dependencies that we need to run our models: ` Building our client logic Now, our goal is to record our voice, send it to the backend, and then receive a voice response from it. To record our audio, we need to use client-side functions, which means we need to use client components. In our case, we don’t want to transform our whole page to use client capabilities and have the whole tree in the client bundle; instead, we would prefer to use Server components and import our client components to progressively enhance our application. So, let’s create a separate component that will handle the client-side logic. Inside our app folder, let's create a components folder, and here, we will be creating our component: ` Let’s go ahead and initialize our component. I went ahead and added a button with some styles in it: ` And then import it into our Page Server component: ` Now, if we run our app, we should see the following: Awesome! Now, our button doesn’t do anything, but our goal is to record our audio and send it to someplace; for that, let us create a hook that will contain our logic: ` We will use two APIs to record our voice: navigator and MediaRecorder. The navigator API will give us information about the user’s media devices like the user media audio, and the MediaRecorder will help us record the audio from it. This is how they’re going to play out together: ` Let’s explain this code step by step. First, we create two new states. The first one is for keeping track of when we are recording, and the second one stores the instance of our MediaRecorder. ` Then, we’ll create our first method, startRecording. Here, we are going to have the logic to start recording our audio. We first check if the user has media devices available thanks to the navigator API that gives us information about the browser environment of our user: If we don’t have media devices to record our audio, we just return. If they do, then let us create a stream using their audio media device. ` Finally, we go ahead and create an instance of a MediaRecorder to record this audio: ` Then we need a method to stop our recording, which will be our stopRecording. Here, we will just stop our recording in case a media recorder exists. ` We are recording our audio, but we are not storing it anywhere. Let’s add a new useEffect and ref to accomplish this. We would need a new ref, and this is where our chunks of audio data will be stored. ` In our useEffect we are going to do two main things: store those chunks in our ref, and when it stops, we are going to create a new Blob of type audio/mp3: ` It is time to wire this hook with our AudioRecorder component: ` Let’s go to the other side of the coin, the backend! Setting up our Server side We want to use our models on the server to keep things safe and run faster. Let’s create a new route and add a handler for it using route handlers from Next.js. In our App folder, let’s make an “Api” folder with the following route in it: We want to use our models on the server to keep things safe and run faster. Let’s create a new route and add a handler for it using route handlers from Next.js. In our App folder, let’s make an “Api” folder with the following route in it: ` Our route is called ‘chat’. In the route.ts file, we’ll set up our handler. Let’s start by setting up our OpenAI SDK. ` In this route, we’ll send the audio from the front end as a base64 string. Then, we’ll receive it and turn it into a Buffer object. ` It’s time to use our first model. We want to turn this audio into text and use OpenAI’s Whisper Speech-To-Text model. Whisper needs an audio file to create the text. Since we have a Buffer instead of a file, we’ll use their ‘toFile’ method to convert our audio Buffer into an audio file like this: ` Notice that we specified “mp3”. This is one of the many extensions that the Whisper model can use. You can see the full list of supported extensions here: https://platform.openai.com/docs/api-reference/audio/createTranscription#audio-createtranscription-file Now that our file is ready, let’s pass it to Whisper! Using our OpenAI instance, this is how we will invoke our model: ` That’s it! Now, we can move on to the next step: using Llama 3.1 to interpret this text and give us an answer. We’ll use two methods for this. First, we’ll use ‘ollama’ from the ‘ollama-ai-provider’ package, which lets us use this model with our locally running Ollama. Then, we’ll use ‘generateText’ from the Vercel AI SDK to generate the text. Side note: To make our Ollama run locally, we need to write the following command in the terminal: ` ` Finally, we have our last model: TTS from OpenAI. We want to reply to our user with audio, so this model will be really helpful. It will turn our text into speech: ` The TTS model will turn our response into an audio file. We want to stream this audio back to the user like this: ` And that’s all the whole backend code! Now, back to the frontend to finish wiring everything up. Putting It All Together In our useRecordVoice.tsx hook, let's create a new method that will call our API endpoint. This method will also take the response back and play to the user the audio that we are streaming from the backend. ` Great! Now that we’re getting our streamed response, we need to handle it and play the audio back to the user. We’ll use the AudioContext API for this. This API allows us to store the audio, decode it and play it to the user once it’s ready: ` And that's it! Now the user should hear the audio response on their device. To wrap things up, let's make our app a bit nicer by adding a little loading indicator: ` Conclusion In this blog post, we saw how combining multiple AI models can help us achieve our goals. We learned to run AI models like Llama 3.1 locally and use them in our Next.js app. We also discovered how to send audio to these models and stream back a response, playing the audio back to the user. This is just one of many ways you can use AI—the possibilities are endless. AI models are amazing tools that let us create things that were once hard to achieve with such quality. Thanks for reading; now, it’s your turn to build something amazing with AI! You can find the complete demo on GitHub: AI Assistant with Whisper TTS and Ollama using Next.js...

What does it actually look like to build software with AI today? Not in theory, but in practice. cover image

What does it actually look like to build software with AI today? Not in theory, but in practice.

What does it actually look like to build software with AI today? Not in theory, but in practice. At the Leadership Exchange, this was the question at the center of the Developer Panel, where leaders from across the industry unpacked what’s really changing inside engineering teams and what organizations need to do right now to keep up. The Developer Panel at the Leadership Exchange explored the cutting edge of AI in software engineering and examined what organizations should focus on today to prepare for the future. Moderated by Jeff Cross, Co-Founder & CEO at Nx, the panel featured Victor Savkin, Cofounder & CTO at Nx, Alex Sover, Vice President of Engineering at OpenAP, Brent Zucker, Senior Director of Engineering at Visa, and Jonathan Fontanez, AI Engineering Lead at This Dot Labs. Panelists shared insights into how AI is transforming the software development lifecycle and how teams can adopt tools effectively while preparing for organizational change. Panelists discussed emerging workflows, including CI-in-the-loop, agentic healing, and context engineering. They examined how validation, code reviews, and PRDs are evolving alongside AI capabilities and how teams are integrating external sources such as production traces to improve quality and reliability. The discussion also covered what the next generation of agentic tools might look like and how these capabilities will shape engineering practices in the near future. Adoption of AI comes with challenges. Teams often rely on plugins or extensions without foundational understanding, and individual contributors may fear displacement. Panelists emphasized that education, governance, and skill-building are essential for teams to manage AI agents effectively while maintaining quality. They also highlighted the need to standardize workflows and ensure organizational alignment to fully leverage AI capabilities. The conversation extended beyond technical challenges to organizational implications. Panelists discussed how teams can avoid issues like Conway’s Law, manage distributed teams effectively, and evolve engineering practices alongside AI adoption. Leadership and management strategies play a crucial role in ensuring that AI integration delivers meaningful outcomes while maintaining efficiency and alignment with business objectives. Key Takeaways - AI workflows require both technical and organizational preparation. - Education, governance, and skill development are essential for successful implementation. - Forward-looking teams are rethinking validation, CI pipelines, and context management to fully leverage agentic AI. The discussion highlighted that adopting AI at the cutting edge is not just about new tools - it is about rethinking processes, workflows, and organizational culture. Companies that embrace this holistic approach are most likely to succeed in leveraging AI to its full potential. Are you interested in more conversations like this? Message us for an invite to the next, or for a private discussion around these topics. Tracy can be reached at tlee@thisdot.co....

Let's innovate together!

We're ready to be your trusted technical partners in your digital innovation journey.

Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.

Prefer email? hi@thisdot.co