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.
Sidebar Help item
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 “{itemName}”
</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.
Permalinks
/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).