
Marketplace Add Extension
Scaffold Sitecore Marketplace extension points—custom fields and dashboard widgets—with React/Next.js boilerplate wired to marketplace client hooks.
Install
npx skills add https://github.com/vercel-labs/sitecore-skills --skill marketplace-add-extensionWhat is this skill?
- Custom field extension template at app/custom-field/page.tsx with marketplace client context
- Dashboard widget template at app/dashboard-widget/page.tsx for stats and quick actions
- Client components using useMarketplaceClient and useAppContext from marketplace providers
- shadcn-style Input, Label, Skeleton patterns for loading and inline editor UX
- Boilerplate oriented to notify the host on field value changes
Adoption & trust: 20 installs on skills.sh; 3 GitHub stars; 3/3 security scanners passed (skills.sh audits).
Recommended Skills
Entra App Registrationmicrosoft/azure-skills
Azure Aigatewaymicrosoft/azure-skills
Lark Openapi Explorerlarksuite/cli
Supabasesupabase/agent-skills
Firebase Auth Basicsfirebase/agent-skills
Firebase Data Connectfirebase/agent-skills
Journey fit
Primary fit
Build phase is where marketplace apps and host extension routes are implemented against Sitecore’s extension model. Integrations subphase reflects embedding UI into Sitecore content editor and dashboard via marketplace extension APIs.
Common Questions / FAQ
Is Marketplace Add Extension safe to install?
skills.sh reports 3 of 3 security scanners passed. Review the Security Audits panel on this page before installing in production.
SKILL.md
READMESKILL.md - Marketplace Add Extension
# Extension Point Boilerplate Templates ## Custom Field (`custom-field`) Route: `app/custom-field/page.tsx` A custom field appears inline in the Sitecore content editor. It receives and returns field values. ```tsx "use client"; import { useEffect, useState } from "react"; import { useMarketplaceClient, useAppContext } from "@/components/providers/marketplace"; import { Input } from "@/components/ui/input"; import { Label } from "@/components/ui/label"; import { Skeleton } from "@/components/ui/skeleton"; export default function CustomFieldPage() { const { client } = useMarketplaceClient(); const appContext = useAppContext(); const [value, setValue] = useState(""); const loading = !appContext; const handleChange = async (newValue: string) => { setValue(newValue); // Notify the host of the value change // The exact mutation depends on your field type }; if (loading) return <Skeleton className="h-10 w-full" />; return ( <div className="p-2 space-y-2"> <Label htmlFor="field">Field Label</Label> <Input id="field" value={value} onChange={(e) => handleChange(e.target.value)} placeholder="Enter value..." /> </div> ); } ``` ## Dashboard Widget (`dashboard-widget`) Route: `app/dashboard-widget/page.tsx` A widget displayed on the Sitecore dashboard. Good for stats, summaries, and quick actions. ```tsx "use client"; import { useEffect, useState } from "react"; import type { UserInfo } from "@sitecore-marketplace-sdk/client"; import { useMarketplaceClient, useAppContext } from "@/components/providers/marketplace"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; import { Alert, AlertDescription } from "@/components/ui/alert"; export default function DashboardWidgetPage() { const { client } = useMarketplaceClient(); const [data, setData] = useState<UserInfo | null>(null); const [loading, setLoading] = useState(true); const [error, setError] = useState<string | null>(null); useEffect(() => { if (!client) return; async function fetchData() { try { const { data: user } = await client.query("host.user"); setData(user); } catch (err) { setError(err instanceof Error ? err.message : "Failed to load"); } finally { setLoading(false); } } fetchData(); }, [client]); if (loading) { return ( <Card> <CardHeader><Skeleton className="h-6 w-32" /></CardHeader> <CardContent><Skeleton className="h-20 w-full" /></CardContent> </Card> ); } if (error) { return <Alert variant="destructive"><AlertDescription>{error}</AlertDescription></Alert>; } return ( <Card> <CardHeader> <CardTitle>My Widget</CardTitle> </CardHeader> <CardContent className="space-y-4"> <p>Welcome, {data?.name}</p> <Button onClick={() => client?.mutate("pages.reloadCanvas")}> Reload Canvas </Button> </CardContent> </Card> ); } ``` ## Pages Context Panel (`pages-context-panel`) Route: `app/pages-context-panel/page.tsx` A side panel in the Pages editor. Receives current page context and can subscribe to page changes. ```tsx "use client"; import { useEffect, useState } from "react"; import type { PagesContext } from "@sitecore-marketplace-sdk/client"; import { useMarketplaceClient, useAppContext } from "@/components/providers/marketplace"; import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/card"; import { Separator } from "@/components/ui/separator"; import { Badge } from "@/components/ui/badge"; import { Skeleton } from "@/components/ui/skeleton"; export default function PagesContextPanelPage() { const { client } = useMarketplaceClient(); const [page, setPage] = useState<PagesContext | null>(null); const [loading, setL