Skip to main content
Nexus Design System
GitHub

Skeleton

Skeleton shows a pulsing placeholder where content is still loading. Use it to keep the layout steady until data arrives. For a short wait with no known layout, use Spinner.

'use client';

import { Skeleton } from '@/components/nxds/components/skeleton/skeleton';

export default function SkeletonCardSkeleton() {
  return (
    <div className="nx:flex nx:w-80 nx:flex-col nx:gap-4">
      <Skeleton className="nx:h-40 nx:w-full nx:rounded-lg" />
      <div className="nx:flex nx:items-center nx:gap-3">
        <Skeleton className="nx:size-10 nx:rounded-full" />
        <div className="nx:flex nx:flex-1 nx:flex-col nx:gap-2">
          <Skeleton className="nx:h-4 nx:w-1/2" />
          <Skeleton className="nx:h-3 nx:w-3/4" />
        </div>
      </div>
    </div>
  );
}

Installation

npx nxds-cli@latest add skeleton

Run npx nxds-cli@latest init first if nxds isn’t set up in your app yet. See Install.

Usage

import { Skeleton } from '@/components/nxds/components/skeleton/skeleton';

Examples

Circle

Use a round placeholder for an avatar or icon.

'use client';

import { Skeleton } from '@/components/nxds/components/skeleton/skeleton';

export default function SkeletonCircle() {
  return <Skeleton className="nx:size-12 nx:rounded-full" />;
}

Text lines

Stack bars of different widths to stand in for a paragraph.

'use client';

import { Skeleton } from '@/components/nxds/components/skeleton/skeleton';

export default function SkeletonTextLines() {
  return (
    <div className="nx:flex nx:flex-col nx:gap-2">
      <Skeleton className="nx:h-4 nx:w-full" />
      <Skeleton className="nx:h-4 nx:w-full" />
      <Skeleton className="nx:h-4 nx:w-4/5" />
    </div>
  );
}

Props

Skeleton

Skeleton adds no props of its own; it accepts the props of the element or primitive it wraps.

Skeleton shows a pulsing placeholder where content is still loading. Use it to keep the layout steady until data arrives. For a short wait with no known layout, use Spinner.

<script setup lang="ts">
import { Skeleton } from '@/components/skeleton';
</script>

<template>
  <div class="nx:flex nx:w-80 nx:flex-col nx:gap-4">
    <Skeleton class="nx:h-40 nx:w-full nx:rounded-lg" />
    <div class="nx:flex nx:items-center nx:gap-3">
      <Skeleton class="nx:size-10 nx:rounded-full" />
      <div class="nx:flex nx:flex-1 nx:flex-col nx:gap-2">
        <Skeleton class="nx:h-4 nx:w-1/2" />
        <Skeleton class="nx:h-3 nx:w-3/4" />
      </div>
    </div>
  </div>
</template>

Installation

  1. Copy and paste the following code into your project.

    components/skeleton/Skeleton.vue
    <script setup lang="ts">
    import type { HTMLAttributes } from 'vue';
    
    import { cn } from '../../lib/utils';
    
    export interface SkeletonProps {
      class?: HTMLAttributes['class'];
    }
    
    const props = defineProps<SkeletonProps>();
    </script>
    
    <template>
      <div
        data-slot="skeleton"
        :class="cn('nx:animate-pulse nx:rounded-md nx:bg-muted', props.class)"
      />
    </template>
    
    components/skeleton/index.ts
    export { default as Skeleton, type SkeletonProps } from './Skeleton.vue';
    
  2. Keep each file at the path shown above it.

    Paths are relative to packages/vue/src/. Keep the same folders under your @/ root, and the imports between files work without edits.

Usage

import { Skeleton } from '@/components/skeleton';

Examples

Circle

Use a round placeholder for an avatar or icon.

<script setup lang="ts">
import { Skeleton } from '@/components/skeleton';
</script>

<template>
  <Skeleton class="nx:size-12 nx:rounded-full" />
</template>

Text lines

Stack bars of different widths to stand in for a paragraph.

<script setup lang="ts">
import { Skeleton } from '@/components/skeleton';
</script>

<template>
  <div class="nx:flex nx:flex-col nx:gap-2">
    <Skeleton class="nx:h-4 nx:w-full" />
    <Skeleton class="nx:h-4 nx:w-full" />
    <Skeleton class="nx:h-4 nx:w-4/5" />
  </div>
</template>

Props

Skeleton

Skeleton adds no props of its own; it accepts the props of the element or primitive it wraps.