DEV Community

Cover image for What is the NuxtIsland component? 🏝️
Michał Kuncio
Michał Kuncio

Posted on • Edited on • Originally published at michalkuncio.com

What is the NuxtIsland component? 🏝️

Nuxt Island is a cool yet experimental feature of Nuxt 3. It's a special built-in component that lets you render the component fully on the server which means zero client-side JavaScript served to the browser. Even if you are using SSR and the HTML content is rendered on the server, client-side JS is still served and used during hydration. With the NuxtIsland component, there is no hydration at all.

When it will come in handy? For example, when we don't need our component to be interactive but we still need some JavaScript logic to make it work.

Let's take a look at some examples:

  • using syntax highlighting library: most of these libraries are quite heavy and we don't need any client-side interactivity when the component is rendered. We might want to get colored syntax from the server and not need any further action regarding syntax highlighting.
  • using heavy date utility library: libraries like moment.js (and yes, I know that it's heavy and not maintained anymore) are also quite heavy. When we need to parse some date, calculate differences, or check timezones we usually want to make it once and serve it to the user.
  • using utility libraries like lodash: with that kind of libraries, we are usually using some utility function like for example converting from snake_case to camelCase and maybe it's not necessary to ship this function to the production bundle?

These are great examples of when it may be a good idea to run some JS code on a server, calculate or render something and return it to the browser without any JS. Of course there are some use cases when you may want these libraries used on the client but we will focus on the case when we don't need any interactivity.

Let's see how we can make it with NuxtIsland component!

How to use the NuxtIsland component?

NuxtIsland component is a part of the experimental server components feature of Nuxt 3. If you want to use server components, you have to enable it in nuxt.config:

// nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    componentIslands: true
  }
})
Enter fullscreen mode Exit fullscreen mode

Let's test how it works! To better understand how server components work, we will try to use some heavy library to make the difference more visible. Let's install moment.js which is perfect for that regarding the size of this library.

npm install moment --save
Enter fullscreen mode Exit fullscreen mode

To make the test, let's create the component called 'Hello.vue':

<!-- components/Hello.vue -->
<template>
    <div>
        <h1>Hello</h1>
        {{ date }}
    <div>
</template>

<script setup lang="ts">
import moment from 'moment';
const date = moment().format('MMMM Do YYYY, h:mm:ss a');
</script>
Enter fullscreen mode Exit fullscreen mode

As you can see, we are importing the moment.js library and using it to format the current date. Let's use it as a normal component and show it in the app.vue. Please note that we don't have to import the **Hello.vue* component, because of Nuxt auto-imports.

<!-- app.vue -->
<template>
    <Hello />
</template>
Enter fullscreen mode Exit fullscreen mode

Let's run the project. The rendered component should look like this:

rendered component

When we examine our network requests, we can see that the component-related client-side script is downloaded by the browser.

classic component networks

Although 4kb is not something to be afraid of, we might ask the question "Ok, but this component isn't interactive at all. Why do I even need JS for that?".

Let's fix it with NuxtIsland! 🏝️

Remember our previously created Hello.vue component? Let's move it from /components to /components/islands directory. Now inside the app.vue, instead of using the Hello.vue component directly, we will make use of the NuxtIsland component.

<!-- app.vue -->
<template>
    <NuxtIsland name="Hello" />
</template>
Enter fullscreen mode Exit fullscreen mode

The NuxtIsland component accepts a prop called "name" which is the name of a component inside /components/islands directory.

Now, when we examine network requests again we can see something interesting:

nuxt island component networks

See? No JS at all for this component! 🔥🚀 But all these tests were run on the dev server. What about production build?

Production build - classic component:

Production build - classic component

Production build - NuxtIsland component:

Production build - NuxtIsland component

What?! We saved 45 kB of data thanks to the NuxtIsland component! 🥳

Summary

All Nuxt features around server components are for now experimental but I'm really excited about the Nuxt and server componens future. You can read more about NuxtIsland and Nuxt server components here:
https://nuxt.com/docs/api/components/nuxt-island
https://nuxt.com/docs/guide/directory-structure/components


If you like my posts, please follow me on Twitter:
https://twitter.com/michalkuncio

Top comments (2)

Collapse
 
woldtwerk profile image
Willi

I think that your example doesn't work correctly. There are a few component types that require a single root element in nuxt. The last time I used island it didn't work properly without a single root.

Collapse
 
michalkuncio profile image
Michał Kuncio

Hmm it's strange because it is working for me but it indeed produces an error: clone.querySelectorAll is not a function

Thanks for pointing it out!