App Launcher Grid

About this block

App Launcher GridPRO

A product bar with a wordmark, plain links, an Apps trigger and an initials avatar. Apps opens a floating card holding a four by three grid of app tiles, each an icon square, a name and a one-liner. On phones the top bar keeps the brand and a fixed bottom tab bar carries five icon tabs, the centre one raising the app grid as a sheet. The card and the sheet stay in the markup and are toggled with CSS.

A product bar with a wordmark, plain links, an Apps trigger and an initials avatar. Apps opens a floating card with a four by three grid of app tiles, and on phones a fixed bottom tab bar carries five icon tabs, the centre one raising the same apps as a sheet.

Upgrade to Pro

Pro blocks install through the shadcn CLI with your license key and ship their full source. Docs and live previews stay open to everyone, so you can read every block's details first.

Upgrade Now

Installation

Swap YOUR_EMAIL and YOUR_KEY for the email and license key on your account. Find your license key on your account page.

Radix flavor

bash
npx shadcn add "https://beste.dev/r/navbar93?email=YOUR_EMAIL&license_key=YOUR_KEY"

Base UI flavor

bash
npx shadcn add "https://beste.dev/r-base/navbar93?email=YOUR_EMAIL&license_key=YOUR_KEY"

This installs the block to components/beste/block/navbar93.tsx; it uses no shadcn primitives, only lucide-react icons.

Quick start

The installed file exports navbar93Demo alongside the block: the exact props behind the preview above. Spread it to get a working navbar in one line.

tsx
import { Navbar93, navbar93Demo } from "@/components/beste/block/navbar93";

export default function Page() {
  return <Navbar93 {...navbar93Demo} />;
}

Then replace the demo with your own props. Written out, a trimmed setup looks like this:

tsx
import { Navbar93 } from "@/components/beste/block/navbar93";

export default function Page() {
  return (
    <Navbar93
      brand="Orbit"
      links={[
        { label: "Dashboard", href: "/dashboard" },
        { label: "Projects", href: "/projects" },
      ]}
      apps={[
        { icon: "mail", name: "Mail", description: "Shared inboxes and threads.", href: "/mail" },
        { icon: "calendar", name: "Calendar", description: "Rooms, rotas and reminders.", href: "/calendar" },
        { icon: "docs", name: "Docs", description: "Write and review together.", href: "/docs" },
      ]}
      allApps={{ label: "Browse all apps", href: "/apps" }}
      tabs={[
        { icon: "home", label: "Home", href: "/" },
        { icon: "search", label: "Search", href: "/search" },
        { icon: "inbox", label: "Inbox", href: "/inbox" },
        { icon: "user", label: "Profile", href: "/profile" },
      ]}
      avatar={{ initials: "NS", href: "/account" }}
      labels={{ apps: "Apps", account: "Your account", close: "Close apps" }}
    />
  );
}

Props

PropTypeDefaultDescription
brandstring–Wordmark on the left
linksNavItem[][]Plain links in the desktop bar
appsAppTile[][]Tiles in the launcher card and the mobile sheet; twelve fill the four by three grid
allAppsNavItem–Link under the grid
tabsTabItem[][]Mobile tab bar links; four of them sit either side of the centre Apps tab
avatar{ initials: string; href: string }–Round initials link on the right
labels{ apps?: string; account?: string; close?: string }{}Apps trigger and tab label, avatar name, and the tab name while the sheet is open
classNamestring–Extra classes for the outer <header>
ts
type IconName =
  | "mail" | "calendar" | "folder" | "docs" | "sheets" | "chat" | "meet" | "tasks"
  | "forms" | "analytics" | "billing" | "admin" | "home" | "search" | "inbox" | "user";

type AppTile = {
  icon: IconName;
  name: string;
  description: string;
  href: string;
};

type TabItem = {
  icon: IconName;
  label: string;
  href: string;
};

type NavItem = {
  label: string;
  href: string;
};

Behavior notes

  • The launcher card, the mobile sheet and its scrim are server-rendered and CSS-toggled, so every app link is in the HTML; the card fades and scales from 98% only under motion-safe:.
  • The card opens on hover or click of the Apps trigger and closes on Escape, on a click outside the header and when the pointer leaves it.
  • The tab bar splits tabs in half around a centre Apps button that carries aria-expanded and aria-controls; tapping a link tab marks it with aria-current="page" and closes the sheet.
  • The sheet rises from behind the tab bar (translate-y-full to translate-y-0), is inert while closed, locks body scroll while open and closes on a tile tap, the scrim or Escape.
  • The blur sits on an inner wrapper rather than the <header>, because backdrop-filter on the header would become the containing block for the fixed tab bar and sheet.

More Navigation blocks

View all Navigation
PRO

navbar87

Icon Rail Flyouts

PRO

navbar109

Account Menu Bar

PRO

navbar103

Single Menu Tabs Panel

Get Pro