Skip to content
WingoUI
ComponentsTemplatesDocsPricingAI agentsBlogChangelog
Components
Buttons & Actions
ButtonButton GroupCopy ButtonDelete ButtonTheme ToggleToggleToggle Group
Inputs
Avatar UploadCalendarCheckboxColor PickerComboboxCron PickerCurrency InputDate PickerDate Range PickerDate Time PickerDuration PickerEmail InputFile UploadFilter BuilderInputInput GroupListboxMasked InputMention InputMonth PickerMulti SelectNumber InputOTP InputPassword InputPhone InputRadio GroupRatingSearch InputSegmented ControlSelectSignature PadSliderSwitchTag InputTextareaTime PickerTimezone Select
Forms
Address InputCSV ImportFieldForm WizardInline EditInvoice line itemsRich Text EditorSchema Builder
Navigation
Back To TopBounce SidebarBreadcrumbCommand MenuGlobal SearchGooey NavHook SidebarNav MenuNav TabsPaginationProximity SidebarScroll ProgressSidebarStepsTable Of ContentsTabsTopbarUser MenuWorkspace Switcher
Overlays
Alert DialogContext MenuDialogDrawerDropdown MenuFamily DrawerHover CardPopoverShare DialogSheetShortcuts DialogTooltipTour
Feedback
AlertBannerCookie ConsentEmoji ReactionEmpty StateNotification BellNotification CenterProgressRoute ProgressSetup ChecklistSkeletonSpinnerToast
Data Display
Approval FlowAvatarBadgeCalendar ViewCode BlockComment ThreadContact cardCountdownDescription ListDiff ViewerFile ListFile managerFolderGanttJSON ViewerKbdLog ViewerMarkdownPresenceSchedulerTagTimelineTree View
Tables & Lists
Audit LogData TableDeal PipelineEditable GridKanbanListMembers tablePermissions MatrixTableTask ListVirtual List
Charts & Stats
Animated CounterArea chartBar chartDonut chartFunnel chartGaugeGitHub ActivityHeatmap calendarLeaderboardLine chartRadar chartRadial barSparklineStat CardTrackerTrend badge
Layout
AccordionApp ShellCardCollapsibleDetail LayoutEntity HeaderPage HeaderScroll AreaSeparatorSettings LayoutSplit ViewToolbar
Media
Audio PlayerCarouselCSV ViewerDOCX EditorDOCX ViewerExcel ViewerFile SystemImage compareImage CropperImage LightboxLocation MapPDF ViewerPowerPoint ViewerQR CodeStep PlayerVideo Player
AI Kit
Agent Status CardChat MessageChat ThreadConversation ListFluid OrbGrid RevealMatrix OrbModel PickerPrompt InputReasoning IndicatorRule BuilderSuggestion ChipsTool Call TimelineUsage MeterVoice InputWorkflow Canvas
Text & Effects
Background PatternGravity LettersMarqueeText AnimateText Rotate
Mobile
Action SheetBottom Tab BarFABHaptic ButtonHero HeaderInstall PromptLarge Title HeaderNotification BannerOnboarding CarouselPicker WheelPull To RefreshSlide To ConfirmSticky CTA BarSwipe DeckSwipeable Tabs
Commerce
Cart drawerCategory pickerCheckout stepsCoupon inputFavorite buttonFilter panelListing cardListing gridOrder trackerPricePrice rangePricing tableProduct galleryQuantity stepperReviewsSeller card
Marketing Sections
App Download SectionBlog Cards SectionCTA SectionFAQ SectionFeature GridFeature ShowcaseHero SectionIntegrations SectionLogo CloudMarketing FooterMarketing HeaderMarketing SectionNewsletter SectionPricing SectionStats SectionSteps SectionTeam SectionTestimonials SectionTimeline SectionVideo Section
Blocks
Admin Dashboard PageAdmin ShellAI Chat PageAPI Keys PageAutomation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox PageInvoice PageKPI DashboardListing Detail PageLogin PageMarketplace Home PageMarketplace Search PageMarketplace ShellMobile App HomeOnboarding FlowPost Listing WizardPricing PageRegister PageSettings PageUsers Admin Page
Templates
About PageAcademy PageAccessibility PageAffiliate PageAI Product PageBlog PageBlog Post PageBug Bounty PageCareers PageChangelog PageCommunity PageCompare PageContact PageCustomer Story PageCustomers PageDemo Booking PageDevelopers PageDocs Home PageDownload PageEnterprise PageEvents PageExperts PageFAQ PageFeature PageGlossary PageHelp Article PageHelp Center PageImpact PageIntegration Detail PageIntegrations PageJob Detail PageLanding PageLaunch PageLegal PageManifesto PagePress PageProduct Tour PagePromo PageReferral PageResearch Report PageRoadmap PageROI Calculator PageSecurity PageSolutions PageStartups PageStatus PageSwitch PageTemplate Gallery PageWaitlist PageYear in Review Page
Hooks & Utilities
AI ChatChart kitCommerceDate utilsFile exportFile typesFiltersForm validationHapticsInvoicingMotion presetsNavigationNumber formatRelative timeRomanian locationsSpreadsheetText matchTonesUIProvideruseClipboarduseConsentuseControllableStateuseCooldownuseDebounceuseKeyboardInsetuseLocaleuseLongPressuseMediaControlsuseMediaQueryuseOverflowItemsusePersistedStateuseScrollEdgesuseScrollStateuseSelectionuseShortcutuseStickToBottom
GalleryTheme

Blocks

API Keys Page

Blocks

API Keys Page React block for Tailwind CSS v4

AI Chat PageAutomation Builder Page
Live props
Content
title
description
docsHref
Behavior
defaultExpiry
maxKeysNo limit
warnDays7 days
locale
State
defaultCreateOpen
Code
import { ApiKeysPage } from "@/components/blocks/api-keys-page"

<ApiKeysPage />
  1. Home
  2. Components
  3. Blocks
  4. API Keys Page
Pro

API Keys Page React block for Tailwind CSS v4

v1.0.0·Added in 1.10.0

The developer settings screen for API keys: list, create with scopes and expiry, reveal the secret once, copy, roll, rename and revoke.

The header names the page, counts the active keys and holds API docs and Create key. Each key shows its name and creator, the masked prefix (ak_live_3f9a••••), status, scopes, created date, when it was last used and when it expires; a key expiring within a week turns amber with "Expires in 5 days". Expired and revoked keys are muted (an active key past its date shows as expired too), and expired ones offer Renew, which opens the create dialog prefilled and replaces the expired row. The ... menu copies the key prefix, renames, rolls or revokes (rolling and revoking ask first, revoking in red). Create key opens a dialog with the cursor in Name: pick scopes and an expiry (the date it lands on shows under it) and press Enter or Create key. Missing fields are named inline, a failed request keeps the form with the error. Then the same dialog shows the secret once in a read-only field, focused and selected, with Copy and a warning; Done turns on after you copy it or tick "I saved this key somewhere safe", and until then outside clicks and Escape do not close it. The secret never goes into a toast, the URL or storage. At the plan's key limit Create key turns off and a hint says why. On phones the keys become cards with the menu as a bottom sheet, and the dialog is a bottom sheet with full-width buttons.

API Keys Page is a Pro React block in the React blocks category, written in TypeScript for React 19 and Tailwind CSS v4. It installs as source with npx wingo-ui@latest add api-keys-page, together with Alert, Alert Dialog, Badge, Button, Checkbox and 13 more and the npm packages motion and lucide-react.

Add to a project

Requirements: React 19 and Tailwind CSS v4, in Next.js (App Router or Pages), Vite or React Router. Installation guide · Next.js setup · Vite setup

npx wingo-ui@latest add api-keys-page

Pro item: the CLI needs a Pro account. See plans

Usage

Import ApiKeysPage from @/components/blocks/api-keys-page.

"use client"

import { ApiKeysPage } from "@/components/blocks/api-keys-page"
import type { ApiKey } from "@/components/blocks/api-keys-page-data"

export function DeveloperKeys({ keys }: { keys: ApiKey[] }) {
  return (
    <ApiKeysPage
      defaultKeys={keys}
      docsHref="https://docs.acme.com/api"
      maxKeys={10}
      onCreate={async (input) => {
        const res = await fetch("/api/keys", { method: "POST", body: JSON.stringify(input) })
        if (!res.ok) throw new Error("The key was not created. Try again.")
        return res.json() as Promise<{ key: ApiKey; secret: string }>
      }}
      onRoll={async (id) => {
        const res = await fetch(`/api/keys/${id}/roll`, { method: "POST" })
        return res.json() as Promise<{ secret: string }>
      }}
      onRevoke={(id) => fetch(`/api/keys/${id}`, { method: "DELETE" })}
    />
  )
}

Props

  • titledefault "API keys"
    ReactNode

    The page title.

  • descriptiondefault "Use these keys to call the API from your servers. Never share them in client code."
    ReactNode

    The line under the title.

  • docsHrefdefault ""
    string

    Adds an API docs link to the header. Empty hides it.

  • keys
    ApiKey[]

    Controlled list: { id, name, prefix, createdAt, lastUsedAt?, expiresAt?, scopes, createdBy?, status: "active" | "expired" | "revoked" }. Pair it with onKeysChange.

  • defaultKeysdefault "API_KEYS_SAMPLE"
    ApiKey[]

    Starting list while uncontrolled. The sample has an active key, one expiring in 5 days, an expired and a revoked one.

  • onKeysChange
    (keys: ApiKey[]) => void

    The list after a create, roll, rename or revoke.

  • scopesdefault "DEFAULT_API_KEY_SCOPES"
    ApiKeyScope[]

    The scope options { value, label, description? }: checkboxes in the create dialog and badges in the list. Default Read, Write and Admin.

  • expiryOptionsdefault "DEFAULT_API_KEY_EXPIRY_OPTIONS"
    ApiKeyExpiryOption[]

    The expiry choices { value, label, days } where days null means never. Default 30 days, 90 days, 1 year and Never.

  • labels
    Partial<ApiKeysPageLabels>

    Merged over DEFAULT_API_KEYS_PAGE_LABELS: every string of the page, the dialogs and the toasts.

  • defaultExpirydefault "90d"
    string

    The expiry preselected in the create dialog.

  • maxKeysdefault 0
    number

    Active keys allowed. At the limit Create key turns off and an info hint explains it. 0 means no limit.

  • warnDaysdefault 7
    number

    An active key expiring within this many days shows an amber "Expires in ...".

  • onCreate
    (input: { name, scopes, expiresIn, renews? }) => Promise<{ key: ApiKey; secret: string }>

    Create the key on your server and return it with its secret, which the dialog shows once. renews is the id of the expired key a Renew replaces. A rejection keeps the form and shows its message. Without it the page makes a local sample key so the flow can be tried.

  • onRevoke
    (id: string) => void | Promise<unknown>

    Revoke was confirmed. The row turns Revoked once it resolves; a rejection shows in the confirmation.

  • onRoll
    (id: string) => Promise<{ secret: string }>

    Adds Roll key to active rows: after a confirmation the new secret is revealed once, like a new key.

  • onRename
    (id: string, name: string) => void | Promise<unknown>

    Adds Rename to the row menu, with a small dialog.

  • defaultCreateOpendefault false
    boolean

    Opens the create dialog on mount, e.g. from an onboarding link.

  • now
    Date | number

    The reference time for last used and expiry warnings; default the live clock (dates show until it hydrates).

  • localedefault ""
    string

    Intl locale for dates and relative times. Empty falls back to the UIProvider locale, then en-US (the demo offers en-GB and de-DE).

  • className
    string

    Classes for the root, a centered column up to 1152px wide. Other div props go to the root too.

  • classNames
    Partial<Record<ApiKeysPageSlot, string>>

    Classes for header, limit, table, empty, dialog and reveal.

Parts

  • DEFAULT_API_KEYS_PAGE_LABELS

    constant

    The English strings; spread it and override what you need for another language.

  • DEFAULT_API_KEY_SCOPES

    constant

    Read, Write and Admin, each with a one-line description.

  • DEFAULT_API_KEY_EXPIRY_OPTIONS

    constant

    30 days, 90 days, 1 year and Never.

  • API_KEYS_SAMPLE

    constant

    Four sample keys (api-keys-page-data.ts): active, expiring in 5 days, expired and revoked.

  • API_KEYS_NOW

    constant

    The reference time the sample is written against (Oct 13, 2026, 10:30); pass it as now in demos and tests.

  • generateDemoApiKey

    function

    Returns a made-up { prefix, secret } for demos and tests. Real keys come from your server.

  • ApiKey

    type

    One key: { id, name, prefix, createdAt, lastUsedAt?, expiresAt?, scopes, createdBy?, status }.

  • ApiKeyStatus

    type

    "active" | "expired" | "revoked".

  • ApiKeyScope

    type

    { value, label, description? }: one scope option.

  • ApiKeyExpiryOption

    type

    { value, label, days }: one expiry choice; days null never expires.

  • ApiKeyCreateInput

    type

    What onCreate receives: { name, scopes, expiresIn, renews? }, expiresIn being the expiry option's value and renews the id of the expired key being renewed.

  • ApiKeyCreateResult

    type

    What onCreate returns: { key, secret }.

  • ApiKeysPageLabels

    type

    The shape of labels.

Examples

Open

No keys yet

defaultKeys={[]}: the empty state with Create key and a docs link.

Open

Create a key

defaultCreateOpen: name, scopes and expiry, then the one-time reveal with Copy and Done.

Open

At the key limit

maxKeys={3} with three active keys: Create key turns off and a hint says why.

Open

Create fails

The first request fails: the form keeps its values and shows the error. Try again and the key appears.

Open

en-GB dates, 14-day warning

locale="en-GB", warnDays={14}, custom copy, with Rename and Roll in the row menu.

Dependencies

motionlucide-reactalertalert-dialogbadgebuttoncheckboxcopy-buttondialogdropdown-menuempty-stateinputpage-headerselecttabletoastuse-controllable-statemotionrelative-timeui-config

Files

  • components/blocks/api-keys-page.tsx
  • components/blocks/api-keys-page-data.ts

FAQ

Is the React API Keys Page block free?

The preview, props and docs are free; copying the source needs a Pro plan. See plans.

How do I install API Keys Page?

Run npx wingo-ui@latest add api-keys-page. It also adds the Wingo UI items it builds on (Alert, Alert Dialog, Badge, Button, Checkbox and 13 more) and the npm packages motion and lucide-react. With shadcn, add the @wingo-ui registry with your API key, then run npx shadcn@latest add @wingo-ui/api-keys-page.

How does API Keys Page behave on phones?

On phones the keys become cards with the menu as a bottom sheet, and the dialog is a bottom sheet with full-width buttons.

See also

Settings PageSettings LayoutCopy ButtonAlert DialogTableAudit Log

More React blocks

Automation Builder PageCheckout PageCRM Contact PageCRM Pipeline PageError PagesInbox Page
All 24 React blocks
PreviousAI Chat PageNext Automation Builder Page