DEV Community

Jason Shimkoski
Jason Shimkoski

Posted on

SSR-Friendly Unique HTML IDs in Vue 3

How many other developers out there have encountered the following scenario:

You have a Vue component that needs to use an HTML id attribute to link elements together:

<template>
  <div>
    <label for="inputId">Label</label>
    <input id="inputId" type="text">
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

But, as it turns out, you need to have multiple instances of that component on the page. To avoid breaking the page with id collisions, you need a unique id for the input element.

Unfortunately, Vue does not provide an instance id for components that you can key off of to do this.

What you'll often see other developers do is something along these lines (this is off the top of my head so forgive any silly errors):

<template>
  <div>
    <label :for="inputId">Label</label>
    <input :id="inputId" type="text">
  </div>
</template>

<script>
let id = 0
export default {
  data() {
    return {
      inputId: null
    }
  },
  created() {
    id++
    this.inputId = id
  }
}
</script>
Enter fullscreen mode Exit fullscreen mode

This will work for the most part until server-side rendering enters the picture. Due to separate thread processing, no matter what you do, id will be out of sync on the server and on the client.

That is a real bummer, but there is a workaround.

I've written vue-uid for this very issue.

It is a tiny directive that generates a unique identifier that is automatically assigned to an element’s id attribute.

Here is a usage example:

<script setup lang="ts">
import { ref } from 'vue'
const input = ref<null | HTMLElement>(null)
</script>

<template>
  <div>
    <label :for="input?.id">Input label</label>
    <input v-uid ref="input" type="text">
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode

The best part of this is that you don't need to write extra code or pull in additional dependencies to figure out how to generate a unique id in the first place, and second, it is SSR-friendly! Slap the v-uid directive on an element and you are off to the races with a unique id you can count on.

If you'd like more understanding into how vue-uid works, be sure to read the Custom Directives documentation.

I hope you found this useful.

Thanks.

Top comments (0)