Widget Generator

Generate customizable widget plugins for the prompts.chat feed system.

You say
Buy it · $49 Read it before you buy $49 Written by f · unverified publisher
Context cost
2.4k tokensestimated from the bundle, loaded when it triggers
Bundle
1 file · 9.4 kBtext throughout, nothing executable
Licence
MITpaid listing
Last change
no release on file
Servers it uses
Noneruns standalone

What it does

Generate customizable widget plugins for the prompts.chat feed system

Installed, it changes the agent in these ways.

What this skill changes about the agent is not written down here yet. The listing was collected from its source, and the description is in its own SKILL.md.

Workflow

Runs a procedure end to end.

content

The skill itself

This is the whole product. A skill is instructions the model reads, so there is nothing behind the listing you cannot see first — the front matter loads with every session, and the body below it loads when the skill triggers.

SKILL.md9.4 kB · 393 lines
--- name: widget-generator description: Generate customizable widget plugins for the prompts.chat feed system ---
6# Widget Generator Skill
7
8This skill guides creation of widget plugins for **prompts.chat**. Widgets are injected into prompt feeds to display promotional content, sponsor cards, or custom interactive components.
9
10## Overview
11
12Widgets support two rendering modes:
131. **Standard prompt widget** - Uses default PromptCard styling (like coderabbit.ts)
142. **Custom render widget** - Full custom React component (like book.tsx)
15
16## Prerequisites
17
18Before creating a widget, gather from the user:
19
20| Parameter | Required | Description |
21|-----------|----------|-------------|
22| Widget ID | ✅ | Unique identifier (kebab-case, e.g., my-sponsor) |
23| Widget Name | ✅ | Display name for the plugin |
24| Rendering Mode | ✅ | standard or custom |
25| Sponsor Info | ❌ | Name, logo, logoDark, URL (for sponsored widgets) |
26
27## Step 1: Gather Widget Configuration
28
29Ask the user for the following configuration options:
30
31### Basic Info
32```
33- id: string (unique, kebab-case)
34- name: string (display name)
35- slug: string (URL-friendly identifier)
36- title: string (card title)
37- description: string (card description)
38```
39
40### Content (for standard mode)
41```
42- content: string (prompt content, can be multi-line markdown)
43- type: "TEXT" | "STRUCTURED"
44- structuredFormat?: "json" | "yaml" (if type is STRUCTURED)
45```
46
47### Categorization
48```
49- tags?: string[] (e.g., ["AI", "Development"])
50- category?: string (e.g., "Development", "Writing")
51```
52
53### Action Button
54```
55- actionUrl?: string (CTA link)
56- actionLabel?: string (CTA button text)
57```
58
59### Sponsor (optional)
60```
61- sponsor?: {
62 name: string
63 logo: string (path to light mode logo)
64 logoDark?: string (path to dark mode logo)
65 url: string (sponsor website)
66 }
67```
68
69### Positioning Strategy
70```
71- positioning: {
72 position: number (0-indexed start position, default: 2)
73 mode: "once" | "repeat" (default: "once")
74 repeatEvery?: number (for repeat mode, e.g., 30)
75 maxCount?: number (max occurrences, default: 1 for once, unlimited for repeat)
76 }
77```
78
79### Injection Logic
80```
81- shouldInject?: (context) => boolean
82 Context contains:
83 - filters.q: search query
84 - filters.category: category name
85 - filters.categorySlug: category slug
86 - filters.tag: tag filter
87 - filters.sort: sort option
88 - itemCount: total items in feed
89```
90
91## Step 2: Create Widget File
92
93### Standard Widget (TypeScript only)
94
95Create file: src/lib/plugins/widgets/{widget-id}.ts
96
97```typescript
98import type { WidgetPlugin } from "./types";
99
100export const {widgetId}Widget: WidgetPlugin = {
101 id: "{widget-id}",
102 name: "{Widget Name}",
103 prompts: [
104 {
105 id: "{prompt-id}",
106 slug: "{prompt-slug}",
107 title: "{Title}",
108 description: "{Description}",
109 content: {Multi-line content here},
110 type: "TEXT",
111 // Optional sponsor
112 sponsor: {
113 name: "{Sponsor Name}",
114 logo: "/sponsors/{sponsor}.svg",
115 logoDark: "/sponsors/{sponsor}-dark.svg",
116 url: "{sponsor-url}",
117 },
118 tags: ["{Tag1}", "{Tag2}"],
119 category: "{Category}",
120 actionUrl: "{action-url}",
121 actionLabel: "{Action Label}",
122 positioning: {
123 position: 2,
124 mode: "repeat",
125 repeatEvery: 50,
126 maxCount: 3,
127 },
128 shouldInject: (context) => {
129 const { filters } = context;
130
131 // Always show when no filters active
132 if (!filters?.q && !filters?.category && !filters?.tag) {
133 return true;
134 }
135
136 // Add custom filter logic here
137 return false;
138 },
139 },
140 ],
141};
142```
143
144### Custom Render Widget (TSX with React)
145
146Create file: src/lib/plugins/widgets/{widget-id}.tsx
147
148```tsx
149import Link from "next/link";
150import Image from "next/image";
151import { Button } from "@/components/ui/button";
152import type { WidgetPlugin } from "./types";
153
154function {WidgetName}Widget() {
155 return (
156 <div className="group border rounded-[var(--radius)] overflow-hidden hover:border-foreground/20 transition-colors bg-gradient-to-br from-primary/5 via-background to-primary/10 p-5">
157 {/* Custom widget content */}
158 <div className="flex flex-col items-center gap-4">
159 {/* Image/visual element */}
160 <div className="relative w-full aspect-video">
161 <Image
162 src="/path/to/image.jpg"
163 alt="{Alt text}"
164 fill
165 className="object-cover rounded-lg"
166 />
167 </div>
168
169 {/* Content */}
170 <div className="w-full text-center">
171 <h3 className="font-semibold text-base mb-1.5">{Title}</h3>
172 <p className="text-xs text-muted-foreground mb-4">{Description}</p>
173 <Button asChild size="sm" className="w-full">
174 <Link href="{action-url}">{Action Label}</Link>
175 </Button>
176 </div>
177 </div>
178 </div>
179 );
180}
181
182export const {widgetId}Widget: WidgetPlugin = {
183 id: "{widget-id}",
184 name: "{Widget Name}",
185 prompts: [
186 {
187 id: "{prompt-id}",
188 slug: "{prompt-slug}",
189 title: "{Title}",
190 description: "{Description}",
191 content: "",
192 type: "TEXT",
193 tags: ["{Tag1}", "{Tag2}"],
194 category: "{Category}",
195 actionUrl: "{action-url}",
196 actionLabel: "{Action Label}",
197 positioning: {
198 position: 10,
199 mode: "repeat",
200 repeatEvery: 60,
201 maxCount: 4,
202 },
203 shouldInject: () => true,
204 render: () => <{WidgetName}Widget />,
205 },
206 ],
207};
208```
209
210## Step 3: Register Widget
211
212Edit src/lib/plugins/widgets/index.ts:
213
2141. Add import at top:
215```typescript
216import { {widgetId}Widget } from "./{widget-id}";
217```
218
2192. Add to widgetPlugins array:
220```typescript
221const widgetPlugins: WidgetPlugin[] = [
222 coderabbitWidget,
223 bookWidget,
224 {widgetId}Widget, // Add new widget
225];
226```
227
228## Step 4: Add Sponsor Assets (if applicable)
229
230If the widget has a sponsor:
2311. Add light logo: public/sponsors/{sponsor}.svg
2322. Add dark logo (optional): public/sponsors/{sponsor}-dark.svg
233
234## Positioning Examples
235
236### Show once at position 5
237```typescript
238positioning: {
239 position: 5,
240 mode: "once",
241}
242```
243
244### Repeat every 30 items, max 5 times
245```typescript
246positioning: {
247 position: 3,
248 mode: "repeat",
249 repeatEvery: 30,
250 maxCount: 5,
251}
252```
253
254### Unlimited repeating
255```typescript
256positioning: {
257 position: 2,
258 mode: "repeat",
259 repeatEvery: 25,
260 // No maxCount = unlimited
261}
262```
263
264## shouldInject Examples
265
266### Always show
267```typescript
268shouldInject: () => true,
269```
270
271### Only when no filters active
272```typescript
273shouldInject: (context) => {
274 const { filters } = context;
275 return !filters?.q && !filters?.category && !filters?.tag;
276},
277```
278
279### Show for specific categories
280```typescript
281shouldInject: (context) => {
282 const slug = context.filters?.categorySlug?.toLowerCase();
283 return slug?.includes("development") || slug?.includes("coding");
284},
285```
286
287### Show when search matches keywords
288```typescript
289shouldInject: (context) => {
290 const query = context.filters?.q?.toLowerCase() || "";
291 return ["ai", "automation", "workflow"].some(kw => query.includes(kw));
292},
293```
294
295### Show only when enough items
296```typescript
297shouldInject: (context) => {
298 return (context.itemCount ?? 0) >= 10;
299},
300```
301
302## Custom Render Patterns
303
304### Card with gradient background
305```tsx
306<div className="border rounded-[var(--radius)] overflow-hidden bg-gradient-to-br from-primary/5 via-background to-primary/10 p-5">
307```
308
309### Sponsor badge
310```tsx
311<div className="flex items-center gap-2 mb-2">
312 <span className="text-xs font-medium text-primary">Sponsored</span>
313</div>
314```
315
316### Responsive image
317```tsx
318<div className="relative w-full aspect-video">
319 <Image src="/image.jpg" alt="..." fill className="object-cover" />
320</div>
321```
322
323### CTA button
324```tsx
325<Button asChild size="sm" className="w-full">
326 <Link href="https://example.com">
327 Learn More
328 <ArrowRight className="ml-2 h-3.5 w-3.5" />
329 </Link>
330</Button>
331```
332
333## Verification
334
3351. Run type check:
336 ```bash
337 npx tsc --noEmit
338 ```
339
3402. Start dev server:
341 ```bash
342 npm run dev
343 ```
344
3453. Navigate to /discover or /feed to verify widget appears at configured positions
346
347## Type Reference
348
349```typescript
350interface WidgetPrompt {
351 id: string;
352 slug: string;
353 title: string;
354 description: string;
355 content: string;
356 type: "TEXT" | "STRUCTURED";
357 structuredFormat?: "json" | "yaml";
358 sponsor?: {
359 name: string;
360 logo: string;
361 logoDark?: string;
362 url: string;
363 };
364 tags?: string[];
365 category?: string;
366 actionUrl?: string;
367 actionLabel?: string;
368 positioning?: {
369 position?: number; // Default: 2
370 mode?: "once" | "repeat"; // Default: "once"
371 repeatEvery?: number; // For repeat mode
372 maxCount?: number; // Max occurrences
373 };
374 shouldInject?: (context: WidgetContext) => boolean;
375 render?: () => ReactNode; // For custom rendering
376}
377
378interface WidgetPlugin {
379 id: string;
380 name: string;
381 prompts: WidgetPrompt[];
382}
383```
384
385## Common Issues
386
387| Issue | Solution |
388|-------|----------|
389| Widget not showing | Check shouldInject logic, verify registration in index.ts |
390| TypeScript errors | Ensure imports from ./types, check sponsor object shape |
391| Styling issues | Use Tailwind classes, match existing widget patterns |
392| Position wrong | Remember positions are 0-indexed, check repeatEvery value |
393
In the file
SKILL.md1,122 words
Files1
LicenceMIT
Why you can read it

Nothing in a skill executes. The client loads the text and the model follows it, so a skill can be audited the way a runbook is — by reading it.

What it costs in context

Skills are not billed by the call. They are paid for in context: every token the instructions occupy is a token your code, your diff and your conversation cannot use. Here is what this one takes and when it takes it.

≈30
always loaded
The name and description, so the model knows the skill exists and when to reach for it.
2,320
on trigger
The instruction body, read only when the skill fires.
1.2%
of a 200k window
Ten skills this size would take about 12% of the window before you open a file.
050k100k150k200k context window

2.4k tokens, estimated from the bundle at four bytes to the token, held for the rest of the session once it triggers. Middling. Fine to keep on in a project where you use it weekly, worth unloading in one where you never do.

Servers bill, skills cost

A server charges by the month. A skill charges once per session, in context, and then keeps charging it for as long as the session lives.

Before and after

The same question, put to the same model twice: once as it comes, and once with these instructions loaded.

No worked example has been published for this skill yet.

Adoption
Installsnone yet
Ratingno reviews yet

The procedure it runs

The procedure has not been published here. It is in the skill’s own SKILL.md, which its author has not sent to the marketplace yet.

Prose, not code

These steps are written for a model to follow, not executed by a runtime. It can still be told to skip one, and it will say so when it does.

Servers it uses

None. This skill calls no MCP servers at all.

Everything it needs is in the instructions, so it works in a project with nothing connected — the model reads the file and changes how it works with what it can already reach.

It writes no files and reaches no network. All it changes is how the model reasons and writes.

What it asks for
Writes filesno
Network accessno

Read from the allowed-tools line of this skill’s own SKILL.md. A skill grants no permissions of its own — it can only ask for tools your client already has.

What it will not do

Every skill is narrow, and the useful ones say where they stop. These are the jobs this one is the wrong tool for.

What this skill is not for has not been published here. Nothing is implied by that: it is a section the author has not filled in.

What is in the bundle

1 file, 9.4 kB on disk. A bundle is text throughout: the instructions the model reads, plus the templates it fills in.

  • SKILL.md9.4 kB
What is not in it

No dependencies and nothing executable: a skill is text the agent reads, so the bundle is 1 file you can review in full before installing. The MIT licence covers the templates and examples as well as the instructions.

Install

Installing copies the bundle into your project. Nothing runs at install time — the files sit on disk until the model reads them.

$49 once
Widget Generator · MIT · f
one-time
Price$49 once
LicenceMIT — the author’s, unchanged by this purchase
Paid throughStripe, once, on the card you add at the checkout
Keeps workingfor good — the files are yours once they are on disk
Updatesevery update its author ships, delivered through this account

You can read the whole bundle before paying — the SKILL.md above is the product, not a preview of it. What the money buys is the delivery: the folder packaged and handed to your machine by key, every update its author ships, and our support if it does not do what this listing says. The terms of use are MIT, set by the author and unchanged by buying it here.

Payment runs through Stripe, on a page like this one rather than a redirect. Once there is an account it joins the same mcprush invoice as everything else you run, so there is never a second card to enter.

Which clients pick it up on their own

A skill is a folder of text. A client with a skills folder reads it without being told; everywhere else the same text works, it is just handed to the model rather than found.

Claude Code.claude/skills/
Claude Desktop
ChatGPT
Cursor.cursor/skills/
VS Code.github/skills/
Codex CLI.agents/skills/
Gemini CLI.gemini/skills/
Grok.grok/skills/
Zed.agents/skills/
Windsurf.windsurf/skills/
Agent SDK.claude/skills/
HTTP / API
This release
Versionnot versioned
Publishedno release date on file
Price$49
Referencef/widget-generator

Versions

Its author publishes no version number, so there is nothing here to pin to: what you install is the folder as it stands today. Instructions change more often than APIs do — a skill can be rewritten entirely without anything it depends on moving.

v
  • No earlier releases have been published to the marketplace.
Pinning

Nothing to pin to: this skill carries no version number of its own. What you install is what the folder holds on the day you install it.

Reviews

no reviews yet · no installs yet

Nobody has reviewed this skill yet. The rating is the mean of the reviews written here, so there is none until somebody writes the first.

Who can post

Only accounts that have had the skill installed for fourteen days, so a review is written after living with it rather than after reading it. Publishers may reply once.

Who wrote it

F
f

Publishes on mcprush.

0 servers listed3 skills listednot claimed
Profile
Publisher
Servers0