What is the NuxtIsland component? 🏝️
Tags: nuxt, vue, webdev, frontend
Published: 2023-10-28 16:37:59

***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:

```ts
// nuxt.config.ts
export default defineNuxtConfig({
  experimental: {
    componentIslands: true
  }
})
```

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.

```bash
npm install moment --save
```

To make the test, let's create the component called 'Hello.vue':
```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>
```
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.

```vue
<!-- app.vue -->
<template>
    <Hello />
</template>
```
Let's run the project. The rendered component should look like this:

![rendered component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vcftr7c2sqoqkdaxrapb.png)

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

![classic component networks](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/phvmzabo2upm1ozys4cb.png)

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.

```vue
<!-- app.vue -->
<template>
    <NuxtIsland name="Hello" />
</template>
```

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/eikf237fb0qnmbvc2diw.png)

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](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/wf61w2kynhe1pkadxogl.png)

***Production build*** - NuxtIsland component:

![Production build - NuxtIsland component](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bno4wbu07nonb67mdjbm.png)

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: 
<a href="https://nuxt.com/docs/api/components/nuxt-island" target=_blank>https://nuxt.com/docs/api/components/nuxt-island</a> 
<a href="https://nuxt.com/docs/guide/directory-structure/components" target=_blank>https://nuxt.com/docs/guide/directory-structure/components</a>

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