Skip to content

Nuxt 3 Demo App with Prerender and SSR

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.

Introduction

The quest for an optimal web application involves numerous factors, such as performance, user experience, and search engine optimization (SEO). Nuxt 3 provides excellent features out-of-the-box that can help you tackle these aspects efficiently.

This article will guide you in creating a Nuxt 3 application using Server Side Rendering (SSR) and pre-rendering capabilities. We'll craft an application that offers a seamless user experience, superior performance, and improved SEO.

Server Side Rendering in Nuxt 3

Enhancing User Experience and SEO with SSR

In the world of web development, Server Side Rendering (SSR) has gained significant traction. It refers to the server rendering the webpage upon each request rather than the client. With SSR, your web page arrives fully formed at the client's doorstep, reducing the time for the first painting.

The advantage of SSR extends beyond just performance and user experience. It's also a darling of search engine crawlers, which find it easier to index your website with fully formed page content at the time of their crawl. In simple terms, it's like providing a tour guide to lead the search engine around your website, ensuring they get all the spots!

The Power of SSR in Nuxt 3

Nuxt 3 has built-in support for SSR by default. It allows you to optimize your application by loading the data before rendering the page. To take advantage of SSR, you simply build your application as you usually would. In this case, using the fetch() method to load some.

<script setup>
import { ref } from 'vue'

const data = ref(null)

async function fetchData() {
  const response = await fetch('https://api.example.com/data')
  const jsonData = await response.json()
  data.value = jsonData
}

fetchData()
</script>

<template>
  <div>
    <h1>Data fetched from the server</h1>
    <pre>{{ data }}</pre>
  </div>
</template>

In this example, the fetchData function fetches the data before rendering the page. The data then gets displayed within the <pre> tag.

Sidenote, if you wanted to disable SSR in your Nuxt application, you would do so in your nuxt.config.ts file:

export default defineNuxtConfig({
  ssr: false # this usually defaults to true
})

More details on how this works can be found in the rendering modes section in the official Nuxt 3 documentation.

Pre-rendering in Nuxt 3

Amplifying Application Performance with Pre-rendering

While SSR has its advantages, another superhero in our story is pre-rendering. Pre-rendering refers to the process of generating the static HTML pages of a site in advance. It's like preparing a feast before the guests arrive so you can serve them promptly.

Like SSR, pre-rendering enhances SEO, as search engines can index fully rendered pages. Especially for content-heavy applications, pre-rendering can give a turbo boost to performance, leading to better user engagement and retention.

Leverage Pre-rendering with Nuxt 3

Nuxt 3 supports SSR and Static Site Generation (SSG), including pre-rendering. To enable prerendering, you need to export your routes in nuxt.config.ts:

export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: ['/route1', '/route2', '/route3']
    }
  }
})

These routes will be pre-rendered during the build phase, allowing for swift navigation. Let's update our application to pre-render the users' list:

<script setup>
import { ref } from 'vue'

const users = ref([])

async function fetchUsers() {
  const response = await fetch('https://api.example.com/users')
  const userJson = await response.json()
  users.value = userJson
}

fetchUsers()
</script>

<template>
  <div>
    <h1>Users</h1>
    <ul>
      <li v-for="user in users" :key="user.id">
        {{ user.name }}
      </li>
    </ul>
  </div>
</template>

In the nuxt.config.ts, include the users' route for pre-rendering:

export default defineNuxtConfig({
  nitro: {
    prerender: {
      routes: ['/users']
    }
  }
})

Going beyond with Nuxt 3

While SSR and pre-rendering are significant for performance and SEO, Nuxt 3 offers more advanced features like hot module replacement, Vue 3 integration, improved error handling, and more. Nuxt 3 also has different kinds of rendering modes for different applications; in our SSR case, we used the default Universal rendering mode. Leveraging these features allows you to develop robust, high-performance, and user-friendly applications.

Conclusion

In this article, we delved into the concepts of SSR and pre-rendering in Nuxt 3. We explored how these techniques contribute to enhancing performance, user experience, and SEO. You can create exceptional web applications by integrating Vue 3's capabilities with Nuxt 3's robust features.

A well-structured, performant, and SEO-friendly application not only attract users but also retains them. Embrace the power of Nuxt 3 and Vue 3 in your development journey. 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

JavaScript Marathon: Exploring Nuxt 3 and Composition API cover image

JavaScript Marathon: Exploring Nuxt 3 and Composition API

Wrapping up our week of free live trainings, @temitopedavid_ walked us through setting up and using Nuxt 3 with the composition API. It's pretty in-depth and for the sake of this wrap-up, I will direct you to the repo itself so you can look through it and see how it works. The event is also available on Youtube for you to watch as well. Nuxt 3 is a very powerful hybrid Vue framework. If you'd like to learn more, check out the documentation....

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....

Improving the Performance of Vue 3 Applications Using v-memo and KeepAlive cover image

Improving the Performance of Vue 3 Applications Using v-memo and KeepAlive

Introduction When building a Vue application, you will encounter performance issues as your app grows, causing it to run slower than it should. Most performance problems in web apps arise from performing tasks repeatedly, even when there is no need to. For example, if you had a list of thousands of items, and had to re-render all items when a single thing changed, you'd quickly encounter performance problems. The ideal solution would be to update only what changes. For the most part, VueJS does this well, and Vue 3 came with many performance improvements out of the box. However, in more complex applications, we may need more fine-grained control over what gets re-rendered and what does not. In this article, we are going to look at how we can use v-memo, and KeepAlive as solutions to performance problems in Vue applications. Two leading solutions to performance problems in Vue JS Memoization Memoization is like a superpower that helps your app remember things without having to constantly redo the same calculations, or processes over and over again. This allows the applications to perform faster and more efficiently, which is the ultimate goal for any web developer. Think about it; when you were a kid, your teachers always taught you to memorize things to save time. The same is valid for web applications. With memoization, they can remember the results of a calculation or process, so they don't have to waste time recalculating it every time they need the same result. For example, imagine you have a website that requires users to enter their birthdates to access certain content. If a user enters their birthdate for the first time, the application will calculate their age. With memoization, the next time the user comes to the website and enters their birthdate, the application can use the previously computed result instead of recalculating it from scratch. That's the beauty of memoization! It saves time and resources, and gives the user a faster and smoother experience. Try memoization if you want your web application to perform at its best. You'll be amazed at how much of a difference it makes! To take advantage of this in Vue, we'll be using the v-memo directive. More on this shortly. Caching Caching works by storing a copy of frequently used data and resources so that the application can access them quickly without having to go through the entire process of rendering and fetching the data from scratch. Think of it like this. When you visit a website for the first time, the browser has to fetch all the resources needed to display the page. But if you see the same website again, the browser can use the cached data, resulting in a faster and smoother experience for the user. We can take advantage of caching in our Vue applications using KeepAlive. Using v-memo V-memo was added in Vue 3.2 and, as far as I am aware, will not be back-ported to Vue 2. You can use v-memo by passing the directive to the element/component whose dependencies you want to memoize. In this case, this would be an element/component that would be computationally expensive to re-render each time a dependency changed. Here's an example of how you could use the v-memo directive: ` Note that it accepts an array of dependency values. And if every value in the array is the same as the last render, updates for the entire sub-tree will be skipped. The dependency values are those that's changes you'd like to be checked and memoized anytime they change. You can learn more about how v-memo works from the official Vue JS documentation. In this case, if the value of dependencyA or dependencyB changed, we would re-render the children of the div. However, if neither dependencyA nor dependencyB changed, we would skip the re-rendering process. This means that any computationally intensive tasks that were needed to occur in the re-render would not be triggered, and as a result, our application would perform better. Using KeepAlive Another alternative solution to performance issues is caching, where the KeepAlive option comes in. KeepAlive is a built-in vue component that allows us to cache component instances when dynamically switching between multiple components conditionally. Using KeepAlive in Vue 3 is straightforward. You can wrap the components you want to cache inside a KeepAlive component. Here's a sample code: ` In this example, we use the KeepAlive component to conditionally cache the ComponentA and ComponentB instances, which are dynamically switched using the currentComponent reactive property. With the KeepAlive component, we can maintain the state of these components even when they are not active, which can lead to improved performance. Conclusion In this article, we talked about how we can improve the performance of our VueJS applications using memoization and caching. In the case of memoization, we can use the v-memo VueJS directive that was introduced in Vue 3.2. Alternatively, when we want to cache component instances, we can use the built-in Vue KeepAlive component. By utilizing both v-memo and KeepAlive, you can optimize the performance of your Vue 3 applications, resulting in faster and smoother user experiences. That being said, if you are looking to start a new Vue JS project and need help with how to structure your project, feel free to check out our Vue JS starter.dev GitHub showcases, which showcase (no kidding) a mini-GitHub clone application built using Vue in different ways (e.g., using Nuxt, Quasar], Vite, etc.). Alternatively, if you are looking to start a new project without worrying about all the config required, you can check out the [Vue JS starter kit instead. Thanks for checking this out!...

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