Add Studio pages
Studio discovers plugins/*/studio/index.tsx at build time. Plugin code imports Studio APIs through @tilecast/studio, not arbitrary dashboard internals.
Add management routes
Section titled “Add management routes”The normal plugin route is the manifest’s studio.route, usually /plugins/<directory>.
import { Puzzle } from "lucide-react";import { defineStudioPlugin, PluginPage } from "@tilecast/studio";
export default defineStudioPlugin({ id: "transit_alerts", icon: Puzzle, routes: [ { index: true, element: <PluginPage pluginId="transit_alerts" /> }, { path: "new", element: <NewFeedPage /> }, { path: ":id", element: <FeedPage /> }, ],});The host wraps management routes in the normal plugin installation gate.
Use route handles for breadcrumbs and resource loaders when a detail page needs a name in the Studio header.
Use plugin translations
Section titled “Use plugin translations”Keep plugin strings in studio/locales/en.json, es.json, and ru.json. Use usePluginTranslation from @tilecast/studio.
The locale tests require matching keys in each supported language. Shared Studio wording stays in shared namespaces; plugin-specific wording stays with the plugin.
Add a standalone route
Section titled “Add a standalone route”A plugin can own an absolute route outside its management subtree when the product needs it. Declare the path in studio.additionalRoutes, then contribute it with standaloneRoutes.
Each route chooses an installation gate and whether it mounts inside the authenticated Studio chrome or as a top-level route with its own shell.
Forms uses /forms for its submitter portal and /approvals for its reviewer inbox. The host refuses collisions with core routes and other plugins.
Add secondary navigation
Section titled “Add secondary navigation”Use secondaryNavigation when a plugin needs an item below Activity and above Settings.
The contribution owns its icon, translated label, route, and optional visibility query. The generic sidebar does not interpret plugin permissions.
Forms uses this for Approvals. Its visibility query asks the Forms API whether the signed-in user can review at least one Form.
A failed visibility query hides the item instead of breaking the sidebar.
The same item appears in the iOS app’s native navigation, after the same visibility check. You don’t write any Swift for that. The app can’t draw your React icon, so add an optional iconToken from the shared icon tokens if one fits. Without it, the app shows a generic plugin icon. Item IDs use lowercase letters, digits, and hyphens.
Use the shared Studio kit
Section titled “Use the shared Studio kit”@tilecast/studio is the supported plugin boundary. It exposes plugin chrome, API requests, session information, translations, confirmation and toast helpers, action menus, targeting controls, date inputs, pagination, and regional formatting.
If a reusable primitive is missing, expose it through that boundary instead of importing a private dashboard module.