In-app help

A feature is not “done” until a user inside the app can find out how to use it. TinyCld packages contribute their own help topics and choose where to surface them from the UI. The help system handles indexing, the drawer, search, and permalinks — you write markdown and add entry points.

Authoring topics

Drop a help/ directory at the root of your package and declare it in manifest.ts:

const manifest = {
    name: 'Example',
    slug: 'example',
    // ...
    help: { directory: 'help' },
}

Each topic is a single markdown file. The filename (without .md) becomes the topic ID:

---
title: Getting started
summary: Quick orientation for new users
tags: [intro, onboarding]
order: 10
---

## What this package does

...

title and summary are required. tags (string array) and order (number, lower sorts first) are optional. Lead with task-oriented prose (“To do X, …”), not API documentation.

Run pnpm run packages:generate from tinycld/ after adding or renaming topics. Topics surface in the global help hub at /a/<org>/help, on a per-package help screen, and through the right-slide drawer.

Surfacing entry points

Three patterns, layered. Pick what fits your package.

A persistent entry point in your package’s sidebar. Add it as the last item, separated by a divider, so it doesn’t compete with primary nav:

import { openHelpPackage } from '@tinycld/core/lib/help/open-help'
import { SidebarDivider, SidebarItem } from '@tinycld/core/components/sidebar-primitives'
import { HelpCircle } from 'lucide-react-native'

// ...inside your SidebarNav children:
<SidebarDivider />
<SidebarItem
    label="Help"
    icon={HelpCircle}
    closesDrawer
    onPress={() => openHelpPackage('example')}
/>

openHelpPackage(slug) opens the drawer to your package’s topic index. Use this when you want one always-visible entry that doesn’t presume which topic the user wants.

Contextual HelpIcon next to a title

For screens with a clear concept attached, drop a HelpIcon next to the page or section title. It opens the drawer to that specific topic:

import { HelpIcon } from '@tinycld/core/components/help/HelpIcon'

<View className="flex-row items-center gap-2">
    <Text className="text-2xl font-bold text-foreground">My Items</Text>
    <HelpIcon topic="example:getting-started" size={18} />
</View>

HelpIcon accepts topic (a <pkg>:<id> literal type, so misspellings fail typecheck), size, and tone ('muted' | 'foreground' | 'accent').

Toolbar HelpIcon with computed topic

If your package’s main screen is a single view that changes meaning by state (a folder browser, a multi-section list), put a HelpIcon in the toolbar’s right cluster and pick the topic from current state. Extract the mapping into a helper, not inline:

import type { HelpTopicId } from '@tinycld/core/lib/help/types'

function helpTopicForSection(section: string, isSearchActive: boolean): HelpTopicId {
    if (isSearchActive) return 'example:search'
    if (section === 'archive') return 'example:archive'
    return 'example:getting-started'
}

// ...inside the component:
const helpTopic = helpTopicForSection(activeSection, isSearchActive)
// ...inside the toolbar's right-side cluster:
<HelpIcon topic={helpTopic} size={18} />

This gives one always-present help affordance whose target adapts to context — better than scattering icons across only some title states.

Inside dialogs

For dialogs that explain a feature concept (sharing, importing, exporting), add a HelpIcon next to the dialog title. This is the moment a user is most likely to wonder “how does this work” — meet them there:

<View className="px-6 pb-4 flex-row items-center gap-2" style={{ paddingTop: 28 }}>
    <Text className="text-foreground flex-1" style={{ fontSize: 28 }} numberOfLines={1}>
        Share &ldquo;{itemName}&rdquo;
    </Text>
    <HelpIcon topic="example:sharing" size={20} />
</View>

The flex-1 + numberOfLines={1} on the title keeps long values from pushing the icon off-screen.

Cross-linking between topics

Inside a topic body, use help:// URLs to link to other topics. The markdown renderer intercepts them and opens the drawer instead of navigating away:

For details on permissions, see [sharing](help://example:sharing).

Opening help imperatively

From any component, openHelp('<pkg>:<id>') opens the drawer to a specific topic; openHelpPackage('<pkg>') opens it to the package index. Both come from @tinycld/core/lib/help/open-help. Use the imperative form for things like keyboard shortcut handlers or “Learn more” links inside form errors.

/a/[orgSlug]/help/[pkg]/[topic] is a real route — shareable in chat or docs. The global hub at /a/[orgSlug]/help has full-text search across every present package’s topics (weighted: title > tags > summary > body).