Skip to content
zedkit
@zedtech/zedkit-ui

OfflineNote

A hook reporting browser online state plus an alert-style note with overridable wording.

beta@zedtech/zedkit-ui

Wraps: (none)

Invoice drafts

  • INV-2041Harbor Studio
    €1,280.00
    Waiting to sync
  • INV-2042Northwind Bakery
    €346.50
    Waiting to sync
View props table
Who is it for?
Developers telling the user the app lost connectivity.
When should I use it?
At the top of a page or panel when `useOnlineStatus()` is false.
When should I pick something else?
For inline operation states — use `StatusLabel`.

Use it

Examples import from the package. With copied source, import from @/components/ui/offline-note instead.

Offline note
import { Heading, OfflineNote } from "@zedtech/zedkit-ui";

<OfflineNote />
<Heading level={3}>Invoice drafts</Heading>
// …the list of drafts, each marked "Waiting to sync"

Wired to online state

Delivery note

Order #1043 · Canvas tote bag · not saved yet

"use client";

import { Button, OfflineNote, useOnlineStatus } from "@zedtech/zedkit-ui";

export function DeliveryNote({ onSave }: { onSave: () => void }) {
  const online = useOnlineStatus();
  return (
    <>
      {online ? null : <OfflineNote title="No connection">Try again when you are back.</OfflineNote>}
      <Button disabled={!online} onClick={onSave}>
        Save note
      </Button>
    </>
  );
}

Custom wording

Your cart

2 items · €58.00

import { Button, OfflineNote } from "@zedtech/zedkit-ui";

<OfflineNote title="No connection">Your cart is saved on this device. Reconnect to pay.</OfflineNote>

Kit not installed yet?

You get
Every component from one import, with the theme tokens included. Updates arrive with your package manager.
You need
  • React 19 and Tailwind CSS 4, for example a Next.js app created with the Tailwind option.
  1. Install

    Terminal
    pnpm add @zedtech/zedkit-ui @fontsource-variable/inter @fontsource-variable/space-grotesk
  2. Load the styles

    Tailwind does not scan node_modules, so the @source line points it at the kit's class names. The path is relative to this file.

    src/app/globals.cssReplace the contents
    @import "tailwindcss";
    @import "@zedtech/zedkit-ui/styles.css";
    @source "../../node_modules/@zedtech/zedkit-ui/src/**/*.{ts,tsx}";
    @source not "../../node_modules/@zedtech/zedkit-ui/src/**/*.test.*";
    
  3. Pick a look

    Set data-identity="glass" on <html> so the finished app matches the site. Fresh app: replace src/app/layout.tsx. Existing app: merge, and keep ThemeProvider and other providers.

    src/app/layout.tsxReplace the contents
    import "./globals.css";
    import "./fonts";
    
    export default function RootLayout({ children }: { children: React.ReactNode }) {
      return (
        <html lang="en" data-identity="glass">
          <body>{children}</body>
        </html>
      );
    }
    
  4. Load the fonts

    The Glass look uses Inter and Space Grotesk; these imports self-host them.

    src/app/fonts.tsCreate the file
    import "@fontsource-variable/inter";
    import "@fontsource-variable/space-grotesk";
    
  5. Import and render

    src/app/page.tsxReplace the contents
    import { Heading, OfflineNote } from "@zedtech/zedkit-ui";
    
    export default function Page() {
      return (
        <main className="px-page-gutter py-section-sm">
          <OfflineNote />
          <Heading level={3}>Invoice drafts</Heading>
          // …the list of drafts, each marked "Waiting to sync"
        </main>
      );
    }
    

Package version 2.0.1.

Props

Prop

Type

Accessibility

role=alert announces the note as soon as it appears, so render it only when the state changes, not on every page load. The wifi icon is hidden from assistive technology (aria-hidden); the title and the text carry the message, so write both. Say what is kept and what to do next ("Your cart is saved on this device. Reconnect to pay.") and disable the actions that cannot work offline so a keyboard user does not trigger a failing request. Icon positioning comes from --spacing-alert-* theme tokens.

Troubleshooting

The note never shows — `useOnlineStatus()` starts `true` and syncs after mount, so it stays hidden during server render and on a connected device; test with the browser devtools Offline switch. The note shows nothing on a device with a dead server — `navigator.onLine` only reports whether a network interface is up (a captive portal still reads online), so also handle failed requests. The note is announced twice — it already has `role="alert"`; do not wrap it in another live region. The hook is used in a server component — it needs a client component (`"use client"`). Default wording does not fit — pass `title` and `children` (or only one of them).

On this page