Vue 3 Integration

Copy-paste Vue 3 components and composables for LoremFaces placeholder avatars.

Basic Usage

The simplest way to use LoremFaces in Vue - just use the URL in a template:

<template>
  <img
    src="https://www.loremfaces.net/96/id/1.jpg"
    alt="User avatar"
    width="96"
    height="96"
    class="avatar"
  />
</template>

<style scoped>
.avatar {
  border-radius: 50%;
}
</style>

Reusable Avatar Component

A flexible Vue 3 component with props for size, ID, and styling:

Avatar.vue

<script setup lang="ts">
import { computed } from 'vue'

interface Props {
  id?: 1 | 2 | 3 | 4 | 5
  size?: 24 | 42 | 48 | 96 | 128 | 256
  alt?: string
  random?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  id: 1,
  size: 96,
  alt: 'User avatar',
  random: false,
})

const src = computed(() => {
  if (props.random) {
    return `https://www.loremfaces.net/${props.size}/random.jpg`
  }
  return `https://www.loremfaces.net/${props.size}/id/${props.id}.jpg`
})
</script>

<template>
  <img
    :src="src"
    :alt="alt"
    :width="size"
    :height="size"
    loading="lazy"
    class="avatar"
  />
</template>

<style scoped>
.avatar {
  border-radius: 50%;
  object-fit: cover;
}
</style>

Usage

<template>
  <Avatar :id="2" :size="128" />
  <Avatar random :size="48" />
</template>

Composable

A Vue 3 composable for generating avatar URLs:

useLoremFaces.ts

export function useLoremFaces() {
  const getUrl = (
    size: 24 | 42 | 48 | 96 | 128 | 256,
    id?: 1 | 2 | 3 | 4 | 5
  ): string => {
    if (id) {
      return `https://www.loremfaces.net/${size}/id/${id}.jpg`
    }
    return `https://www.loremfaces.net/${size}/random.jpg`
  }

  const sizes = [24, 42, 48, 96, 128, 256] as const
  const ids = [1, 2, 3, 4, 5] as const

  return { getUrl, sizes, ids }
}

// Usage in component
<script setup>
import { useLoremFaces } from './useLoremFaces'

const { getUrl, ids } = useLoremFaces()
</script>

<template>
  <div>
    <img
      v-for="id in ids"
      :key="id"
      :src="getUrl(48, id)"
      :alt=`User ${id}`
    />
  </div>
</template>

Avatar Stack Component

Display overlapping avatars for team previews:

AvatarStack.vue

<script setup lang="ts">
interface Props {
  count?: number
  size?: number
}

const props = withDefaults(defineProps<Props>(), {
  count: 5,
  size: 48,
})

const avatars = computed(() =>
  Array.from({ length: Math.min(props.count, 5) }, (_, i) => i + 1)
)
</script>

<template>
  <div class="avatar-stack">
    <img
      v-for="(id, index) in avatars"
      :key="id"
      :src=`https://www.loremfaces.net/${size}/id/${id}.jpg`
      :alt=`Team member ${id}`
      :width="size"
      :height="size"
      :style="{ marginLeft: index === 0 ? 0 : '-12px' }"
      class="avatar"
    />
  </div>
</template>

<style scoped>
.avatar-stack {
  display: flex;
}
.avatar {
  border-radius: 50%;
  border: 2px solid white;
}
</style>
Tip: Use v-memo on avatar lists that don't change to prevent unnecessary re-renders.

Nuxt 3 Usage

Works the same in Nuxt 3 with auto-imports:

<!-- components/Avatar.vue -->
<script setup lang="ts">
const props = defineProps<{
  id?: 1 | 2 | 3 | 4 | 5
  size?: 24 | 42 | 48 | 96 | 128 | 256
}>()

const src = computed(() =>
  `https://www.loremfaces.net/${props.size ?? 96}/id/${props.id ?? 1}.jpg`
)
</script>

<template>
  <NuxtImg
    :src="src"
    :width="size ?? 96"
    :height="size ?? 96"
    loading="lazy"
    class="rounded-full"
  />
</template>

Next Steps

Check out more integration guides: