Skip to main content

LoadingPage

LoadingPage

Full-page branded loading screen with logo and progress

Tags: component feedback loading page

View Demo

A full-viewport loading screen for initial app loads, route transitions, or long-running operations. Displays the Classic Homes branded logo with optional progress bar and message.

Import​

<script>
  import { LoadingPage } from '@classic-homes/theme-svelte';
</script>
import { LoadingPage } from '@classic-homes/theme-react';

Basic Usage​

{#if appLoading}
  <LoadingPage loading message="Loading your experience..." />
{/if}

Props​

Prop Type Default Description
loading boolean true Whether loading is active
message string - Loading message (e.g. "Loading...")
progress number - Determinate progress value (0–100)
showLogo boolean true Show branded LoadingLogo
logoVariant 'light' | 'dark' 'dark' Logo color variant
delay number 200 Delay in ms before showing
class string - Additional CSS classes

Layout​

The component renders a fixed full-viewport overlay with centered content:

  1. Logo — Animated Classic Homes logo (or Spinner if showLogo=false)
  2. Progress bar — Shown only when progress is provided
  3. Message — Subtle pulsing text below the indicator
  4. Status region — Screen reader announcement of state

Delay​

The default 200ms delay prevents a flash of loading screen for fast page transitions. Set delay={0} to show immediately.

<!-- Immediate display -->
<LoadingPage loading delay={0} />

<!-- Custom delay -->
<LoadingPage loading delay={500} />

Examples​

App Initialization​

<script>
  import { LoadingPage } from '@classic-homes/theme-svelte';

  let appReady = $state(false);

  onMount(async () => {
    await initializeApp();
    appReady = true;
  });
</script>

{#if !appReady}
  <LoadingPage loading message="Initializing..." />
{/if}

{#if appReady}
  <App />
{/if}

With Progress​

Show determinate progress for operations with known duration:

<script>
  let progress = $state(0);
  let message = $state('Downloading resources...');

  async function loadApp() {
    for (let i = 0; i <= 100; i += 10) {
      progress = i;
      if (i >= 50) message = 'Processing data...';
      if (i >= 80) message = 'Almost done...';
      await new Promise((r) => setTimeout(r, 200));
    }
  }
</script>

<LoadingPage loading {progress} {message} />

Use a plain spinner instead of the branded logo:

<LoadingPage loading showLogo={false} message="Loading..." />

Light Variant (Dark Background)​

If your app has a dark initial background:

<LoadingPage loading logoVariant="light" class="bg-gray-900" />

Route Transition​

<!-- SvelteKit layout -->
<script>
  import { navigating } from '$app/stores';
  import { LoadingPage } from '@classic-homes/theme-svelte';
</script>

{#if $navigating}
  <LoadingPage loading message="Loading page..." delay={300} />
{/if}

<slot />

React Suspense Fallback​

import { Suspense } from 'react';
import { LoadingPage } from '@classic-homes/theme-react';

function App() {
  return (
    <Suspense fallback={<LoadingPage loading message="Loading..." />}>
      <Routes />
    </Suspense>
  );
}

Accessibility​

  • Uses role="status" and aria-live="polite" for screen reader announcements
  • Provides an sr-only status region combining message and progress percentage
  • The animated logo has aria-hidden="true" on the SVG and a separate sr-only "Loading" text
  • Animation respects prefers-reduced-motion
On this page