Claude-skill-registry dashboard-create-screen
Create a new screen in the Multi-site Dashboard with automatic route registration
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/dashboard-create-screen" ~/.claude/skills/majiayu000-claude-skill-registry-dashboard-create-screen && rm -rf "$T"
skills/data/dashboard-create-screen/SKILL.mdDashboard Create Screen Skill
Creates new screens in
client/dashboard with automatic route discovery and registration.
Step 1: Discover Available Routes
First, find all router files and extract available routes.
Find Router Files
Use Glob to discover router files:
client/dashboard/app/router/*.tsx client/dashboard/app/router/*.ts
Extract Routes from Each File
For each router file, use Grep to extract route information.
Find exported route constants:
export\s+const\s+(\w+Route)\s*=\s*createRoute
Extract parent relationships:
getParentRoute:\s*\(\)\s*=>\s*(\w+Route)
Extract path segments:
path:\s*['"]([^'"]+)['"]
Extract component import paths:
import\(\s*['"]([^'"]+)['"]\s*\)
Build Route Information
For each discovered route, record:
- Route variable name (e.g.,
)siteBackupsRoute - Parent route name (e.g.,
)siteRoute - Path segment (e.g.,
)'backups' - Source file path
- Component directory (derived from import path)
Step 2: Discover Navigation Menus (After Route Selection)
Menu discovery happens after the user selects a parent route. Find menus relative to the route's location.
Determine Menu Search Path
Based on the selected parent route's import path, determine where to search for menus:
-
Extract the component directory from the parent route's lazy import
- Example:
→ search inimport('../../sites/backups')client/dashboard/sites/ - Example:
→ search inimport('../../me/profile')client/dashboard/me/
- Example:
-
Use Glob to find menu files in that area:
client/dashboard/{area}/**/*-menu/index.tsx -
Also check the app-level menu for top-level routes:
client/dashboard/app/*-menu/index.tsx
Extract Menu Information
For each discovered menu file, use Grep to find:
Existing menu items pattern:
<ResponsiveMenu\.Item\s+to=
Route references in menu:
to=\{?\s*[`'"/]([^`'"}\s]+)
This helps understand the menu's structure and where to add new items.
Menu Item Pattern
Menu items use
ResponsiveMenu.Item:
<ResponsiveMenu.Item to="/path/to/screen"> { __( 'Menu Label' ) } </ResponsiveMenu.Item>
Conditional menu items check feature support:
{ siteTypeSupports.featureName && ( <ResponsiveMenu.Item to={ `/sites/${ siteSlug }/feature` }> { __( 'Feature' ) } </ResponsiveMenu.Item> ) }
Step 3: Gather User Input
Ask the user for the following using AskUserQuestion:
- Parent Route: Present discovered routes grouped by source file
- Screen Name: lowercase-with-dashes (e.g.,
)custom-settings - Route Path: URL path segment (e.g.,
)custom-settings - Page Title: Human-readable title (e.g.,
)Custom settings - Page Description (optional): Description shown below title
- Add to Navigation Menu?: Yes or No
Step 4: Determine File Locations
Based on the selected parent route's import path, determine where to create the component.
Pattern: If parent imports from
../../sites/backups, new screen goes in client/dashboard/sites/{screen-name}/
For sites area:
client/dashboard/sites/{screen-name}/index.tsx
For me area: client/dashboard/me/{screen-name}/index.tsx
For other areas: Follow the same pattern from parent's import path
Step 5: Create Component File
Generate a basic component with the standard layout.
Screen Template
import { __ } from '@wordpress/i18n'; import { PageHeader } from '../../components/page-header'; import PageLayout from '../../components/page-layout'; export default function {ComponentName}() { return ( <PageLayout header={ <PageHeader title={ __( '{PageTitle}' ) } description={ __( '{PageDescription}' ) } /> } > {/* Content goes here */} </PageLayout> ); }
Step 6: Register the Route
Add the route definition to the same router file as the parent route.
Route Definition Pattern
Add after other route exports in the file:
export const {routeName}Route = createRoute( { head: () => ( { meta: [ { title: __( '{PageTitle}' ), }, ], } ), getParentRoute: () => {parentRoute}, path: '{routePath}', } ).lazy( () => import( '{componentImportPath}' ).then( ( d ) => createLazyRoute( '{routeId}' )( { component: d.default, } ) ) );
Wire into Route Tree
Find where the parent route is used in the
create*Routes() function and add the new route.
For standalone routes (direct child of main area route):
// Find the routes array (e.g., siteRoutes, meRoutes) // Add the new route to the array siteRoutes.push( newScreenRoute );
For nested routes (child of a feature route):
// Find where parent uses .addChildren() // Add the new route to the children array parentRoute.addChildren( [ existingRoute, newScreenRoute ] )
Step 7: Add Navigation Menu Entry (Optional)
If the user requested a navigation menu entry, add it to the discovered menu file.
Locate Target Menu File
Use the menu discovered in Step 2 based on the route's area:
- From the parent route's import path, extract the area (e.g.,
,sites
,me
)plugins - Glob for
client/dashboard/{area}/**/*-menu/index.tsx - If multiple menus found, present them to the user for selection
- If no area-specific menu found, fall back to
client/dashboard/app/primary-menu/index.tsx
Add Menu Item
Read the target menu file and find an appropriate location (typically before the closing
</ResponsiveMenu> tag).
Build the route path from parent route's path + new screen path:
- If parent path is
and screen path is/sites/$siteSlug
→analytics/sites/${ siteSlug }/analytics - If parent path is
and screen path is/me
→api-keys/me/api-keys
Insert menu item:
<ResponsiveMenu.Item to={ `{fullRoutePath}` }> { __( '{PageTitle}' ) } </ResponsiveMenu.Item>
Match Existing Patterns
Analyze the existing menu items to match the pattern:
- If menu uses template literals with
, use the same patternsiteSlug - If menu uses simple strings, use simple strings
- If menu items have conditional wrappers, ask user if one is needed
Conditional Menu Items
If the screen requires feature gating (check if similar items in the menu use conditions):
{ siteTypeSupports.{featureName} && ( <ResponsiveMenu.Item to={ `/sites/${ siteSlug }/{routePath}` }> { __( '{PageTitle}' ) } </ResponsiveMenu.Item> ) }
Coding Standards
Follow the coding standards documented in
client/dashboard/docs/.