[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M71MGEN6ZGRVT4E2CH7174JX":3,"skill-same:01M71MGEN6ZGRVT4E2CH7174JX":75},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":23,"publishedAt":44,"linkOnly":45,"markdownContent":46,"markdownBody":47,"frontMatter":48,"refName":52,"commitSha":53,"skillDirectory":54,"forksCount":55,"repositoryHtmlUrl":56,"repositoryHomepageUrl":6,"ownerHtmlUrl":57,"ownerBlogUrl":58,"ownerDescription":59,"updatedAt":60,"install":61,"resources":74},"01M71MGEN6ZGRVT4E2CH7174JX","deno-frontend",null,"Use when working with Fresh framework, creating routes or handlers in Fresh, building web UIs with Preact, or adding Tailwind CSS in Deno. Covers Fresh 2.x project structure, route handlers, islands, createDefine, PageProps, context patterns, and Fresh 1.x to 2.x migration. Essential for any Fresh-related question.","iDorgham\u002FWorkspace-Factory","iDorgham","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F136521493?v=4","01M6CNGBDAHE4ARW3YJEF4X2FD","Dorgham","01M71E8H3CXZ7DJX59MTM9JEB2",1,"MIT","https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Fskills\u002Fofficial_denoland_deno_frontend\u002Fskill.md",[18],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发","SCENARIO","使用场景",[24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43],"frontend","deno","deno frontend","web","with","use","for","essential","framework","context","patterns","project structure","structure","route","fresh","when","question","Tailwind","project","css","2026-11-10 10:56:23",false,"---\nname: deno-frontend\ndescription: Use when working with Fresh framework, creating routes or handlers in Fresh, building web UIs with Preact, or adding Tailwind CSS in Deno. Covers Fresh 2.x project structure, route handlers, islands, createDefine, PageProps, context patterns, and Fresh 1.x to 2.x migration. Essential for any Fresh-related question.\nlicense: MIT\nmetadata:\n  author: denoland\n  version: \"2.4\"\n---\n\n# Deno Frontend Development\n\n## Overview\n\nThis skill covers frontend development in Deno using Fresh 2.x (Deno's web framework), Preact (a lightweight React alternative), and Tailwind CSS. Fresh uses \"island architecture\" where pages render on the server and only interactive parts ship JavaScript to the browser.\n\n## When to Use This Skill\n\n- Creating a new Fresh web application\n- Building interactive UI components (islands)\n- Adding server-rendered pages and routes\n- Integrating Tailwind CSS for styling\n- Choosing between islands (client-side) vs components (server-only)\n- Working with Preact hooks and signals\n\nApply these practices when building web applications in Deno.\n\n## Scope Boundaries\n\nThis skill applies **only** to Fresh\u002FDeno frontend questions. Follow these rules:\n\n- If the user asks about **Next.js, React Native, Vue, Svelte, Angular, or any other framework**, answer using that framework directly. Do not suggest Fresh alternatives.\n- Do not include Fresh imports, `useSignal`, island patterns, or Fresh project structure in responses about other frameworks.\n- Only recommend Fresh when the user explicitly asks about Fresh or is working in a Fresh\u002FDeno project.\n\n## CRITICAL: Never Show Deprecated Syntax\n\nWhen helping users migrate from Fresh 1.x, describe old patterns generically and ONLY show correct Fresh 2.x code. Never write out old dollar-sign import paths or deprecated syntax, even in \"before\u002Fafter\" comparisons.\n\n- Say \"Replace the old dollar-sign import paths with stable Fresh 2.x imports\" — then show only the correct `from \"fresh\"` approach\n- Do NOT write `❌ Old: import { App } from \"$fresh\u002Fserver.ts\"` — this is never acceptable, even as a negative example\n- The strings `_404.tsx` and `_500.tsx` must never appear in your response, even when comparing Fresh 2.x to 1.x. Say \"the old separate error pages\" instead.\n\nOnly demonstrate Fresh 2.x patterns.\n\n## CRITICAL: Fresh 2.x vs 1.x\n\n**Always use Fresh 2.x patterns.** Fresh 1.x is deprecated. Key differences:\n\n- Fresh 2.x uses `import { App } from \"fresh\"` — the old dollar-sign import paths are deprecated\n- Fresh 2.x has no manifest file — the old auto-generated manifest is no longer needed\n- Fresh 2.x uses `vite.config.ts` for dev — the old `dev.ts` entry point is gone\n- Fresh 2.x configures via `new App()` — the old config file is no longer used\n- Fresh 2.x handlers take a single `(ctx)` parameter — the old two-parameter signature is deprecated\n- Fresh 2.x uses a unified `_error.tsx` — the old separate error pages are replaced\n\n**Always use Fresh 2.x stable imports:**\n```typescript\n\u002F\u002F ✅ CORRECT - Fresh 2.x stable\nimport { App, staticFiles } from \"fresh\";\nimport { define } from \".\u002Futils\u002Fstate.ts\"; \u002F\u002F Project-local define helpers\n```\n\n## Fresh Framework\n\nReference: https:\u002F\u002Ffresh.deno.dev\u002Fdocs\n\nFresh is Deno's web framework. It uses **island architecture** - pages are rendered on the server, and only interactive parts (\"islands\") get JavaScript on the client.\n\n### Creating a Fresh Project\n\n```bash\ndeno run -Ar jsr:@fresh\u002Finit\ncd my-project\ndeno task dev    # Runs at http:\u002F\u002F127.0.0.1:5173\u002F\n```\n\n### Project Structure (Fresh 2.x)\n\n```\nmy-project\u002F\n├── deno.json           # Config, dependencies, and tasks\n├── main.ts             # Server entry point\n├── client.ts           # Client entry point (CSS imports)\n├── vite.config.ts      # Vite configuration\n├── routes\u002F             # Pages and API routes\n│   ├── _app.tsx        # App layout wrapper (outer HTML)\n│   ├── _layout.tsx     # Layout component (optional)\n│   ├── _error.tsx      # Unified error page (404\u002F500)\n│   ├── index.tsx       # Home page (\u002F)\n│   └── api\u002F            # API routes\n├── islands\u002F            # Interactive components (hydrated on client)\n│   └── Counter.tsx\n├── components\u002F         # Server-only components (no JS shipped)\n│   └── Button.tsx\n├── static\u002F             # Static assets\n└── utils\u002F\n    └── state.ts        # Define helpers for type safety\n```\n\n**Note:** Fresh 2.x does not use a manifest file, a separate dev entry point, or a separate config file.\n\n### main.ts (Fresh 2.x Entry Point)\n\n```typescript\nimport { App, fsRoutes, staticFiles, trailingSlashes } from \"fresh\";\n\nconst app = new App()\n  .use(staticFiles())\n  .use(trailingSlashes(\"never\"));\n\nawait fsRoutes(app, {\n  dir: \".\u002F\",\n  loadIsland: (path) => import(`.\u002Fislands\u002F${path}`),\n  loadRoute: (path) => import(`.\u002Froutes\u002F${path}`),\n});\n\nif (import.meta.main) {\n  await app.listen();\n}\n```\n\n### vite.config.ts\n\n```typescript\nimport { defineConfig } from \"vite\";\nimport { fresh } from \"@fresh\u002Fplugin-vite\";\nimport tailwindcss from \"@tailwindcss\u002Fvite\";\n\nexport default defineConfig({\n  plugins: [\n    fresh(),\n    tailwindcss(),\n  ],\n});\n```\n\n### deno.json Configuration\n\nA Fresh 2.x project's deno.json looks like this (created by `jsr:@fresh\u002Finit`):\n\n```json\n{\n  \"tasks\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"deno serve -A _fresh\u002Fserver.js\"\n  },\n  \"imports\": {\n    \"fresh\": \"jsr:@fresh\u002Fcore@^2\",\n    \"fresh\u002Fruntime\": \"jsr:@fresh\u002Fcore@^2\u002Fruntime\",\n    \"@fresh\u002Fplugin-vite\": \"jsr:@fresh\u002Fplugin-vite@^1\",\n    \"@preact\u002Fsignals\": \"npm:@preact\u002Fsignals@^2\",\n    \"preact\": \"npm:preact@^10\",\n    \"preact\u002Fhooks\": \"npm:preact@^10\u002Fhooks\",\n    \"@\u002F\": \".\u002F\"\n  }\n}\n```\n\n**Adding dependencies:** Use `deno add` to add new packages:\n\n```sh\ndeno add jsr:@std\u002Fhttp          # JSR packages\ndeno add npm:@tailwindcss\u002Fvite  # npm packages\n```\n\n### Import Reference (Fresh 2.x)\n\n```typescript\n\u002F\u002F Core Fresh imports\nimport { App, staticFiles, fsRoutes } from \"fresh\";\nimport { trailingSlashes, cors, csp } from \"fresh\";\nimport { createDefine, HttpError } from \"fresh\";\nimport type { PageProps, Middleware, RouteConfig } from \"fresh\";\n\n\u002F\u002F Runtime imports (for client-side checks)\nimport { IS_BROWSER } from \"fresh\u002Fruntime\";\n\n\u002F\u002F Preact\nimport { useSignal, signal, computed } from \"@preact\u002Fsignals\";\nimport { useState, useEffect, useRef } from \"preact\u002Fhooks\";\n```\n\n### Key Concepts\n\n**Routes (`routes\u002F` folder)**\n- File-based routing: `routes\u002Fabout.tsx` → `\u002Fabout`\n- Dynamic routes: `routes\u002Fblog\u002F[slug].tsx` → `\u002Fblog\u002Fmy-post`\n- Optional segments: `routes\u002Fdocs\u002F[[version]].tsx` → `\u002Fdocs` or `\u002Fdocs\u002Fv2`\n- Catch-all routes: `routes\u002Fold\u002F[...path].tsx` → `\u002Fold\u002Ffoo\u002Fbar`\n- Route groups: `routes\u002F(marketing)\u002F` for shared layouts without URL path changes\n\n**Layouts (`_app.tsx`)**\n```tsx\nimport type { PageProps } from \"fresh\";\n\nexport default function App({ Component }: PageProps) {\n  return (\n    \u003Chtml>\n      \u003Chead>\n        \u003Cmeta charset=\"utf-8\" \u002F>\n        \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \u002F>\n        \u003Ctitle>My App\u003C\u002Ftitle>\n      \u003C\u002Fhead>\n      \u003Cbody>\n        \u003CComponent \u002F>\n      \u003C\u002Fbody>\n    \u003C\u002Fhtml>\n  );\n}\n```\n\n**Async Server Components**\n```tsx\nexport default async function Page() {\n  const data = await fetchData(); \u002F\u002F Runs on server only\n  return \u003Cdiv>{data.title}\u003C\u002Fdiv>;\n}\n```\n\n## Data Fetching Patterns\n\nFresh 2.x provides two approaches for fetching data on the server. The handler pattern is the recommended default because it demonstrates the full Fresh 2.x architecture and provides the most flexibility.\n\n### Approach A: Handler with Data Object (Recommended)\n\nUse this as the default for data fetching. It uses the full Fresh 2.x handler pattern with typed data passing. Always show the complete setup including `utils\u002Fstate.ts` when demonstrating this pattern.\n\n```tsx\n\u002F\u002F utils\u002Fstate.ts - one-time setup for type-safe handlers\nimport { createDefine } from \"fresh\";\n\nexport interface State {\n  user?: { id: string; name: string };\n}\n\nexport const define = createDefine\u003CState>();\n```\n\n```tsx\n\u002F\u002F routes\u002Fposts.tsx\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\n\n\u002F\u002F Handler fetches data and returns it via { data: {...} }\nexport const handler = define.handlers(async (ctx) => {\n  const response = await fetch(\"https:\u002F\u002Fjsonplaceholder.typicode.com\u002Fposts\");\n  const posts = await response.json();\n  return { data: { posts } };\n});\n\n\u002F\u002F Page receives typed data\nexport default define.page\u003Ctypeof handler>(({ data }) => {\n  return (\n    \u003Cdiv>\n      \u003Ch1>Posts\u003C\u002Fh1>\n      \u003Cul>\n        {data.posts.map((post) => \u003Cli key={post.id}>{post.title}\u003C\u002Fli>)}\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n  );\n});\n```\n\nThis approach also supports auth checks, redirects, and other logic before rendering.\n\n### Approach B: Async Server Components (Shorthand)\n\nFor the simplest cases where you just need to fetch and display data with no auth or redirects:\n\n```tsx\n\u002F\u002F routes\u002Fservers.tsx\nexport default async function ServersPage() {\n  const servers = await db.query(\"SELECT * FROM servers\");\n\n  return (\n    \u003Cdiv>\n      \u003Ch1>Servers\u003C\u002Fh1>\n      \u003Cul>\n        {servers.map((s) => \u003Cli key={s.id}>{s.name}\u003C\u002Fli>)}\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n### Decision Guide\n\n```\nNeed to fetch data on server?\n├─ Yes → Use handler with { data: {...} } return (Approach A)\n│   (supports auth checks, redirects, and typed data passing)\n├─ Simple DB query, no logic? → Async page component is also fine (Approach B)\n└─ No → Just use a regular page component\n```\n\n## Handlers and Define Helpers (Fresh 2.x)\n\nFresh 2.x uses a **single context parameter** pattern for handlers. Always use `(ctx)` as the only parameter.\n\n**Important:** When demonstrating any handler pattern (data fetching, form handling, API routes, auth), always show or reference the `utils\u002Fstate.ts` setup which imports `createDefine` from `\"fresh\"`. This ensures the complete Fresh 2.x architecture is visible.\n\n### Route Handlers\n\nAlways use `define.handlers()` for type-safe route handlers in file-based routes:\n\n```tsx\n\u002F\u002F routes\u002Fapi\u002Fusers.ts\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\n\n\u002F\u002F Single function handles all methods\nexport const handler = define.handlers((ctx) => {\n  return new Response(`Hello from ${ctx.req.method}`);\n});\n\n\u002F\u002F Or method-specific handlers\nexport const handler = define.handlers({\n  GET(ctx) {\n    return Response.json({ users: [] });\n  },\n  async POST(ctx) {\n    const body = await ctx.req.json();\n    return Response.json({ created: true }, { status: 201 });\n  },\n});\n```\n\nNote: Bare handler exports (`export const handler = (ctx) => {...}`) also work but lose TypeScript type safety. Prefer `define.handlers()`.\n\n### The Context Object\n\nThe `ctx` parameter provides everything you need:\n\n```tsx\nexport const handler = (ctx) => {\n  ctx.req          \u002F\u002F The Request object\n  ctx.url          \u002F\u002F URL instance with pathname, searchParams\n  ctx.params       \u002F\u002F Route parameters { slug: \"my-post\" }\n  ctx.state        \u002F\u002F Request-scoped data for middlewares\n  ctx.config       \u002F\u002F Fresh configuration\n  ctx.route        \u002F\u002F Matched route pattern\n  ctx.error        \u002F\u002F Caught error (on error pages)\n\n  \u002F\u002F Methods\n  ctx.render(\u003CJSX \u002F>)           \u002F\u002F Render JSX to Response (JSX only, NOT data objects!)\n  ctx.render(\u003CJSX \u002F>, { status: 201, headers: {...} })  \u002F\u002F With response options\n  ctx.redirect(\"\u002Fother\")        \u002F\u002F Redirect (302 default)\n  ctx.redirect(\"\u002Fother\", 301)   \u002F\u002F Permanent redirect\n  ctx.next()                    \u002F\u002F Call next middleware\n};\n```\n\n### Define Helpers (Type Safety)\n\nCreate a `utils\u002Fstate.ts` file for type-safe handlers:\n\n```tsx\n\u002F\u002F utils\u002Fstate.ts\nimport { createDefine } from \"fresh\";\n\n\u002F\u002F Define your app's state type\nexport interface State {\n  user?: { id: string; name: string };\n}\n\n\u002F\u002F Export typed define helpers\nexport const define = createDefine\u003CState>();\n```\n\nUse in routes:\n\n```tsx\n\u002F\u002F routes\u002Fprofile.tsx\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\nimport type { PageProps } from \"fresh\";\n\n\u002F\u002F Typed handler with data\nexport const handler = define.handlers((ctx) => {\n  if (!ctx.state.user) {\n    return ctx.redirect(\"\u002Flogin\");\n  }\n  return { data: { user: ctx.state.user } };\n});\n\n\u002F\u002F Page receives typed data\nexport default define.page\u003Ctypeof handler>(({ data }) => {\n  return \u003Ch1>Welcome, {data.user.name}!\u003C\u002Fh1>;\n});\n```\n\n### Middleware (Fresh 2.x)\n\n```tsx\n\u002F\u002F routes\u002F_middleware.ts\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\n\nexport const handler = define.middleware(async (ctx) => {\n  \u002F\u002F Before route handler\n  console.log(`${ctx.req.method} ${ctx.url.pathname}`);\n\n  \u002F\u002F Call next middleware\u002Froute\n  const response = await ctx.next();\n\n  \u002F\u002F After route handler\n  return response;\n});\n```\n\n### API Routes\n\n```tsx\n\u002F\u002F routes\u002Fapi\u002Fposts\u002F[id].ts\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\nimport { HttpError } from \"fresh\";\n\nexport const handler = define.handlers({\n  async GET(ctx) {\n    const post = await getPost(ctx.params.id);\n    if (!post) {\n      throw new HttpError(404); \u002F\u002F Uses _error.tsx\n    }\n    return Response.json(post);\n  },\n\n  async DELETE(ctx) {\n    if (!ctx.state.user) {\n      throw new HttpError(401);\n    }\n    await deletePost(ctx.params.id);\n    return new Response(null, { status: 204 });\n  },\n});\n```\n\n## Islands (Interactive Components)\n\nIslands are components that get hydrated (made interactive) on the client. Place them in the `islands\u002F` folder or `(_islands)` folder within routes.\n\n### When to Use Islands\n\n- User interactions (clicks, form inputs)\n- Client-side state (counters, toggles)\n- Browser APIs (localStorage, geolocation)\n\n### Island Example\n\n```tsx\n\u002F\u002F islands\u002FCounter.tsx\nimport { useSignal } from \"@preact\u002Fsignals\";\n\nexport default function Counter() {\n  const count = useSignal(0);\n\n  return (\n    \u003Cdiv>\n      \u003Cp>Count: {count.value}\u003C\u002Fp>\n      \u003Cbutton onClick={() => count.value++}>\n        Increment\n      \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n### Client-Only Code with IS_BROWSER\n\n```tsx\n\u002F\u002F islands\u002FLocalStorageCounter.tsx\nimport { IS_BROWSER } from \"fresh\u002Fruntime\";\nimport { useSignal } from \"@preact\u002Fsignals\";\n\nexport default function LocalStorageCounter() {\n  \u002F\u002F Return placeholder during SSR\n  if (!IS_BROWSER) {\n    return \u003Cdiv>Loading...\u003C\u002Fdiv>;\n  }\n\n  \u002F\u002F Client-only code\n  const stored = localStorage.getItem(\"count\");\n  const count = useSignal(stored ? parseInt(stored) : 0);\n\n  return (\n    \u003Cbutton onClick={() => {\n      count.value++;\n      localStorage.setItem(\"count\", String(count.value));\n    }}>\n      Count: {count.value}\n    \u003C\u002Fbutton>\n  );\n}\n```\n\n### Island Props (Serializable Types)\n\nIslands can receive these prop types:\n- Primitives: string, number, boolean, bigint, undefined, null\n- Special values: Infinity, -Infinity, NaN, -0\n- Collections: Array, Map, Set\n- Objects: Plain objects with string keys\n- Built-ins: URL, Date, RegExp, Uint8Array\n- Preact: JSX elements, Signals (with serializable values)\n- Circular references are supported\n\n**Functions cannot be passed as props.**\n\n### Island Rules\n\n1. **Props must be serializable** - No functions, only JSON-compatible data\n2. **Keep islands small** - Less JavaScript shipped to client\n3. **Prefer server components** - Only use islands when you need interactivity\n\n## Preact\n\nPreact is a 3KB alternative to React. Fresh uses Preact instead of React.\n\n### Preact vs React Differences\n\n| Preact | React |\n|--------|-------|\n| `class` works | `className` required |\n| `@preact\u002Fsignals` | `useState` |\n| 3KB bundle | ~40KB bundle |\n\n### Hooks (Same as React)\n\n```tsx\nimport { useState, useEffect, useRef } from \"preact\u002Fhooks\";\n\nfunction MyComponent() {\n  const [value, setValue] = useState(0);\n  const inputRef = useRef\u003CHTMLInputElement>(null);\n\n  useEffect(() => {\n    console.log(\"Component mounted\");\n  }, []);\n\n  return \u003Cinput ref={inputRef} value={value} \u002F>;\n}\n```\n\n### Signals (Preact's Reactive State)\n\nSignals are Preact's more efficient alternative to useState:\n\n```tsx\nimport { signal, computed } from \"@preact\u002Fsignals\";\n\nconst count = signal(0);\nconst doubled = computed(() => count.value * 2);\n\nfunction Counter() {\n  return (\n    \u003Cdiv>\n      \u003Cp>Count: {count}\u003C\u002Fp>\n      \u003Cp>Doubled: {doubled}\u003C\u002Fp>\n      \u003Cbutton onClick={() => count.value++}>+1\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\nBenefits of signals:\n- More granular updates (only re-renders what changed)\n- Can be defined outside components\n- Cleaner code for shared state\n\n## Tailwind CSS in Fresh (Optional)\n\nTailwind CSS is optional—you don't need it to build a great Fresh app. However, many developers prefer it for rapid styling. Fresh 2.x uses Vite for builds, so Tailwind integrates via the Vite plugin.\n\n### Setup\n\nInstall both Tailwind packages:\n\n```sh\ndeno add npm:@tailwindcss\u002Fvite npm:tailwindcss\n```\n\n**Important:** You need both packages. `@tailwindcss\u002Fvite` is the Vite plugin, and `tailwindcss` is the core library it depends on.\n\nConfigure Vite in `vite.config.ts`:\n```typescript\nimport { defineConfig } from \"vite\";\nimport tailwindcss from \"@tailwindcss\u002Fvite\";\n\nexport default defineConfig({\n  plugins: [tailwindcss()],\n});\n```\n\nAdd the Tailwind import to your CSS file (e.g., `assets\u002Fstyles.css`):\n```css\n@import \"tailwindcss\";\n```\n\nThen import this CSS file in your `client.ts`:\n```typescript\nimport \".\u002Fassets\u002Fstyles.css\";\n```\n\n### Usage\n\n```tsx\nexport default function Button({ children }) {\n  return (\n    \u003Cbutton class=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600\">\n      {children}\n    \u003C\u002Fbutton>\n  );\n}\n```\n\n### Best Practices\n\n1. **Prefer utility classes** over `@apply`\n2. **Use `class` not `className`** (Preact supports both, but `class` is simpler)\n3. **Dark mode**: Use `class` strategy in tailwind.config.js\n\n```tsx\n\u003Cdiv class=\"bg-white dark:bg-gray-900\">\n  \u003Cp class=\"text-gray-900 dark:text-white\">Hello\u003C\u002Fp>\n\u003C\u002Fdiv>\n```\n\n## Building and Deploying\n\n### Development\n\n```bash\ndeno task dev      # Start dev server with hot reload (http:\u002F\u002F127.0.0.1:5173\u002F)\n```\n\n### Production Build\n\n```bash\ndeno task build    # Build for production\ndeno task preview  # Preview production build locally\n```\n\n### Deploy to Deno Deploy\n\n```bash\ndeno task build           # Build first\ndeno deploy --prod        # Deploy to production\n```\n\n## Quick Reference\n\n| Task | Command\u002FPattern |\n|------|-----------------|\n| Create Fresh project | `deno run -Ar jsr:@fresh\u002Finit` |\n| Start dev server | `deno task dev` (port 5173) |\n| Build for production | `deno task build` |\n| Add a page | Create `routes\u002Fpagename.tsx` |\n| Add an API route | Create `routes\u002Fapi\u002Fendpoint.ts` |\n| Add interactive component | Create `islands\u002FComponentName.tsx` |\n| Add static component | Create `components\u002FComponentName.tsx` |\n\n## Common Mistakes\n\n### Using Fresh 1.x Patterns (Most Common LLM Error)\n\n**Using old import specifiers**\n\nThe old dollar-sign Fresh import paths and alpha version imports are deprecated. Always use the stable `fresh` package:\n\n```tsx\n\u002F\u002F ✅ CORRECT - Fresh 2.x stable imports\nimport { App, staticFiles } from \"fresh\";\nimport type { PageProps } from \"fresh\";\n```\n\n**Using two-parameter handlers**\n\nThe old two-parameter handler signature is deprecated. Fresh 2.x uses a single context parameter:\n\n```tsx\n\u002F\u002F ✅ CORRECT - Fresh 2.x uses single context parameter\nexport const handler = {\n  GET(ctx) {  \u002F\u002F Single ctx param\n    return ctx.render(\u003CMyPage \u002F>);\n  }\n};\n```\n\n**Creating legacy files**\n\nFresh 2.x does not use a manifest file, a separate dev entry point, or a separate config file. The correct Fresh 2.x file structure is:\n\n```\nmain.ts           # Server entry\nclient.ts         # Client entry\nvite.config.ts    # Vite config\n```\n\n**Using deprecated context methods**\n\nThe old `renderNotFound()`, bare `render()` without JSX, and `basePath` patterns are deprecated. Use these Fresh 2.x patterns instead:\n\n```tsx\n\u002F\u002F ✅ CORRECT - Fresh 2.x patterns\nthrow new HttpError(404)\nctx.render(\u003CMyComponent \u002F>)\nctx.config.basePath\n```\n\n**Passing data from handlers to pages (VERY COMMON MISTAKE)**\n\nThis is a frequent error. In Fresh 2.x, you cannot pass data through `ctx.render()`. Instead, return an object with a `data` property from the handler:\n\n```tsx\n\u002F\u002F ✅ CORRECT - Return object with data property from handler\nexport const handler = define.handlers(async (ctx) => {\n  const servers = await getServers();\n  return { data: { servers } };  \u002F\u002F Return { data: {...} } object\n});\n\n\u002F\u002F ✅ CORRECT - Link page to handler type with typeof\nexport default define.page\u003Ctypeof handler>(({ data }) => {\n  return \u003Cul>{data.servers.map((s) => \u003Cli>{s.name}\u003C\u002Fli>)}\u003C\u002Ful>;\n});\n\n\u002F\u002F ✅ ALSO CORRECT - Use async page component (simpler when no auth\u002Fredirects needed)\nexport default async function ServersPage() {\n  const servers = await getServers();\n  return \u003Cul>{servers.map((s) => \u003Cli>{s.name}\u003C\u002Fli>)}\u003C\u002Ful>;\n}\n```\n\n**Old task commands in deno.json**\n\nThe old task commands that reference `dev.ts` are deprecated. Use the Vite-based tasks:\n\n```json\n\u002F\u002F ✅ CORRECT - Fresh 2.x tasks\n{\n  \"tasks\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"deno serve -A _fresh\u002Fserver.js\"\n  }\n}\n```\n\n### Island Mistakes\n\n**Putting too much JavaScript in islands**\n```tsx\n\u002F\u002F ❌ Wrong - entire page as an island (ships all JS to client)\n\u002F\u002F islands\u002FHomePage.tsx\nexport default function HomePage() {\n  return (\n    \u003Cdiv>\n      \u003CHeader \u002F>\n      \u003CMainContent \u002F>\n      \u003CFooter \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F ✅ Correct - only interactive parts are islands\n\u002F\u002F routes\u002Findex.tsx (server component)\nimport Counter from \"..\u002Fislands\u002FCounter.tsx\";\n\nexport default function HomePage() {\n  return (\n    \u003Cdiv>\n      \u003CHeader \u002F>\n      \u003CMainContent \u002F>\n      \u003CCounter \u002F>\n      \u003CFooter \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n**Passing non-serializable props to islands**\n```tsx\n\u002F\u002F ❌ Wrong - functions can't be serialized\n\u003CCounter onUpdate={(val) => console.log(val)} \u002F>\n\n\u002F\u002F ✅ Correct - only pass JSON-serializable data\n\u003CCounter initialValue={5} label=\"Click count\" \u002F>\n```\n\n### Other Common Mistakes\n\n**Using `className` instead of `class`**\n```tsx\n\u002F\u002F ❌ Works but unnecessary in Preact\n\u003Cdiv className=\"container\">\n\n\u002F\u002F ✅ Preact supports native HTML attribute\n\u003Cdiv class=\"container\">\n```\n\n**Forgetting to build before deploying Fresh 2.x**\n```bash\n# ❌ Wrong - Fresh 2.x requires a build step\ndeno deploy --prod\n\n# ✅ Correct - build first, then deploy\ndeno task build\ndeno deploy --prod\n```\n\n**Creating islands for non-interactive content**\n```tsx\n\u002F\u002F ❌ Wrong - this doesn't need to be an island (no interactivity)\n\u002F\u002F islands\u002FStaticCard.tsx\nexport default function StaticCard({ title, body }) {\n  return \u003Cdiv class=\"card\">\u003Ch2>{title}\u003C\u002Fh2>\u003Cp>{body}\u003C\u002Fp>\u003C\u002Fdiv>;\n}\n\n\u002F\u002F ✅ Correct - use a regular component (no JS shipped)\n\u002F\u002F components\u002FStaticCard.tsx\nexport default function StaticCard({ title, body }) {\n  return \u003Cdiv class=\"card\">\u003Ch2>{title}\u003C\u002Fh2>\u003Cp>{body}\u003C\u002Fp>\u003C\u002Fdiv>;\n}\n```\n\n**Using old Tailwind plugin**\n\nThe old Fresh 1.x Tailwind plugin is deprecated. Fresh 2.x uses the Vite Tailwind plugin:\n\n```typescript\n\u002F\u002F ✅ CORRECT - Fresh 2.x uses Vite Tailwind plugin\nimport tailwindcss from \"@tailwindcss\u002Fvite\";\n```\n\n**Missing tailwindcss package**\n```sh\n# Error: Can't resolve 'tailwindcss' in '\u002Fpath\u002Fto\u002Fassets'\n\n# ❌ WRONG - Only installed the Vite plugin\ndeno add npm:@tailwindcss\u002Fvite\n\n# ✅ CORRECT - Install both packages\ndeno add npm:@tailwindcss\u002Fvite npm:tailwindcss\n```\n\nThe `@tailwindcss\u002Fvite` plugin requires the core `tailwindcss` package to be installed separately.\n\n## Fresh Alpha Versions (2.0.0-alpha.*)\n\nSome projects use Fresh 2.x alpha releases (e.g., `@fresh\u002Fcore@2.0.0-alpha.29`). These are **not Fresh 1.x** but use a different setup than stable Fresh 2.x:\n\n| Alpha pattern | Stable 2.x pattern |\n|---|---|\n| `dev.ts` entry point | `vite.config.ts` |\n| `@fresh\u002Fplugin-tailwind` | `@tailwindcss\u002Fvite` |\n| `deno run -A --watch dev.ts` | `vite` |\n| Dev server on port 8000 | Dev server on port 5173 |\n| No `client.ts` | Requires `client.ts` |\n| `deno run -A dev.ts build` | `vite build` |\n\n**IMPORTANT:** If you see `dev.ts` in a project with `@fresh\u002Fcore@2.0.0-alpha.*` in `deno.json`, do NOT treat it as a Fresh 1.x artifact. It is the correct entry point for alpha versions. Check the `deno.json` imports to determine which version is in use before suggesting changes.\n\nAlpha projects also use the handler pattern `define.handlers({ GET(ctx) { ... } })` which returns `{ data: {...} }` - this is the same as stable 2.x.\n\n## Migrating from Fresh 1.x to 2.x\n\nIf you have an existing Fresh 1.x project, run the migration tool:\n\n```bash\ndeno run -Ar jsr:@fresh\u002Fupdate\n```\n\nThis tool automatically:\n- Converts old import paths to the new `fresh` package\n- Updates handler signatures to use the single `(ctx)` parameter\n- Removes legacy generated and config files\n- Creates `vite.config.ts` and `client.ts`\n- Updates `deno.json` tasks to use Vite\n- Merges separate error pages into unified `_error.tsx`\n- Updates deprecated context method calls to Fresh 2.x equivalents\n\n### Manual Migration Checklist\n\nIf the tool misses anything:\n\n1. **Imports**: All Fresh imports should come from `fresh` or `fresh\u002Fruntime`\n2. **Handlers**: Should use single `(ctx)` parameter, access request via `ctx.req`\n3. **Files**: Remove any legacy generated files, dev entry points, or old config files\n4. **Tasks**: Update to `vite`, `vite build`, `deno serve -A _fresh\u002Fserver.js`\n5. **Error pages**: Use a single unified `_error.tsx`\n6. **Tailwind**: Use `@tailwindcss\u002Fvite` (the Vite plugin)\n","# Deno Frontend Development\n\n## Overview\n\nThis skill covers frontend development in Deno using Fresh 2.x (Deno's web framework), Preact (a lightweight React alternative), and Tailwind CSS. Fresh uses \"island architecture\" where pages render on the server and only interactive parts ship JavaScript to the browser.\n\n## When to Use This Skill\n\n- Creating a new Fresh web application\n- Building interactive UI components (islands)\n- Adding server-rendered pages and routes\n- Integrating Tailwind CSS for styling\n- Choosing between islands (client-side) vs components (server-only)\n- Working with Preact hooks and signals\n\nApply these practices when building web applications in Deno.\n\n## Scope Boundaries\n\nThis skill applies **only** to Fresh\u002FDeno frontend questions. Follow these rules:\n\n- If the user asks about **Next.js, React Native, Vue, Svelte, Angular, or any other framework**, answer using that framework directly. Do not suggest Fresh alternatives.\n- Do not include Fresh imports, `useSignal`, island patterns, or Fresh project structure in responses about other frameworks.\n- Only recommend Fresh when the user explicitly asks about Fresh or is working in a Fresh\u002FDeno project.\n\n## CRITICAL: Never Show Deprecated Syntax\n\nWhen helping users migrate from Fresh 1.x, describe old patterns generically and ONLY show correct Fresh 2.x code. Never write out old dollar-sign import paths or deprecated syntax, even in \"before\u002Fafter\" comparisons.\n\n- Say \"Replace the old dollar-sign import paths with stable Fresh 2.x imports\" — then show only the correct `from \"fresh\"` approach\n- Do NOT write `❌ Old: import { App } from \"$fresh\u002Fserver.ts\"` — this is never acceptable, even as a negative example\n- The strings `_404.tsx` and `_500.tsx` must never appear in your response, even when comparing Fresh 2.x to 1.x. Say \"the old separate error pages\" instead.\n\nOnly demonstrate Fresh 2.x patterns.\n\n## CRITICAL: Fresh 2.x vs 1.x\n\n**Always use Fresh 2.x patterns.** Fresh 1.x is deprecated. Key differences:\n\n- Fresh 2.x uses `import { App } from \"fresh\"` — the old dollar-sign import paths are deprecated\n- Fresh 2.x has no manifest file — the old auto-generated manifest is no longer needed\n- Fresh 2.x uses `vite.config.ts` for dev — the old `dev.ts` entry point is gone\n- Fresh 2.x configures via `new App()` — the old config file is no longer used\n- Fresh 2.x handlers take a single `(ctx)` parameter — the old two-parameter signature is deprecated\n- Fresh 2.x uses a unified `_error.tsx` — the old separate error pages are replaced\n\n**Always use Fresh 2.x stable imports:**\n```typescript\n\u002F\u002F ✅ CORRECT - Fresh 2.x stable\nimport { App, staticFiles } from \"fresh\";\nimport { define } from \".\u002Futils\u002Fstate.ts\"; \u002F\u002F Project-local define helpers\n```\n\n## Fresh Framework\n\nReference: https:\u002F\u002Ffresh.deno.dev\u002Fdocs\n\nFresh is Deno's web framework. It uses **island architecture** - pages are rendered on the server, and only interactive parts (\"islands\") get JavaScript on the client.\n\n### Creating a Fresh Project\n\n```bash\ndeno run -Ar jsr:@fresh\u002Finit\ncd my-project\ndeno task dev    # Runs at http:\u002F\u002F127.0.0.1:5173\u002F\n```\n\n### Project Structure (Fresh 2.x)\n\n```\nmy-project\u002F\n├── deno.json           # Config, dependencies, and tasks\n├── main.ts             # Server entry point\n├── client.ts           # Client entry point (CSS imports)\n├── vite.config.ts      # Vite configuration\n├── routes\u002F             # Pages and API routes\n│   ├── _app.tsx        # App layout wrapper (outer HTML)\n│   ├── _layout.tsx     # Layout component (optional)\n│   ├── _error.tsx      # Unified error page (404\u002F500)\n│   ├── index.tsx       # Home page (\u002F)\n│   └── api\u002F            # API routes\n├── islands\u002F            # Interactive components (hydrated on client)\n│   └── Counter.tsx\n├── components\u002F         # Server-only components (no JS shipped)\n│   └── Button.tsx\n├── static\u002F             # Static assets\n└── utils\u002F\n    └── state.ts        # Define helpers for type safety\n```\n\n**Note:** Fresh 2.x does not use a manifest file, a separate dev entry point, or a separate config file.\n\n### main.ts (Fresh 2.x Entry Point)\n\n```typescript\nimport { App, fsRoutes, staticFiles, trailingSlashes } from \"fresh\";\n\nconst app = new App()\n  .use(staticFiles())\n  .use(trailingSlashes(\"never\"));\n\nawait fsRoutes(app, {\n  dir: \".\u002F\",\n  loadIsland: (path) => import(`.\u002Fislands\u002F${path}`),\n  loadRoute: (path) => import(`.\u002Froutes\u002F${path}`),\n});\n\nif (import.meta.main) {\n  await app.listen();\n}\n```\n\n### vite.config.ts\n\n```typescript\nimport { defineConfig } from \"vite\";\nimport { fresh } from \"@fresh\u002Fplugin-vite\";\nimport tailwindcss from \"@tailwindcss\u002Fvite\";\n\nexport default defineConfig({\n  plugins: [\n    fresh(),\n    tailwindcss(),\n  ],\n});\n```\n\n### deno.json Configuration\n\nA Fresh 2.x project's deno.json looks like this (created by `jsr:@fresh\u002Finit`):\n\n```json\n{\n  \"tasks\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"deno serve -A _fresh\u002Fserver.js\"\n  },\n  \"imports\": {\n    \"fresh\": \"jsr:@fresh\u002Fcore@^2\",\n    \"fresh\u002Fruntime\": \"jsr:@fresh\u002Fcore@^2\u002Fruntime\",\n    \"@fresh\u002Fplugin-vite\": \"jsr:@fresh\u002Fplugin-vite@^1\",\n    \"@preact\u002Fsignals\": \"npm:@preact\u002Fsignals@^2\",\n    \"preact\": \"npm:preact@^10\",\n    \"preact\u002Fhooks\": \"npm:preact@^10\u002Fhooks\",\n    \"@\u002F\": \".\u002F\"\n  }\n}\n```\n\n**Adding dependencies:** Use `deno add` to add new packages:\n\n```sh\ndeno add jsr:@std\u002Fhttp          # JSR packages\ndeno add npm:@tailwindcss\u002Fvite  # npm packages\n```\n\n### Import Reference (Fresh 2.x)\n\n```typescript\n\u002F\u002F Core Fresh imports\nimport { App, staticFiles, fsRoutes } from \"fresh\";\nimport { trailingSlashes, cors, csp } from \"fresh\";\nimport { createDefine, HttpError } from \"fresh\";\nimport type { PageProps, Middleware, RouteConfig } from \"fresh\";\n\n\u002F\u002F Runtime imports (for client-side checks)\nimport { IS_BROWSER } from \"fresh\u002Fruntime\";\n\n\u002F\u002F Preact\nimport { useSignal, signal, computed } from \"@preact\u002Fsignals\";\nimport { useState, useEffect, useRef } from \"preact\u002Fhooks\";\n```\n\n### Key Concepts\n\n**Routes (`routes\u002F` folder)**\n- File-based routing: `routes\u002Fabout.tsx` → `\u002Fabout`\n- Dynamic routes: `routes\u002Fblog\u002F[slug].tsx` → `\u002Fblog\u002Fmy-post`\n- Optional segments: `routes\u002Fdocs\u002F[[version]].tsx` → `\u002Fdocs` or `\u002Fdocs\u002Fv2`\n- Catch-all routes: `routes\u002Fold\u002F[...path].tsx` → `\u002Fold\u002Ffoo\u002Fbar`\n- Route groups: `routes\u002F(marketing)\u002F` for shared layouts without URL path changes\n\n**Layouts (`_app.tsx`)**\n```tsx\nimport type { PageProps } from \"fresh\";\n\nexport default function App({ Component }: PageProps) {\n  return (\n    \u003Chtml>\n      \u003Chead>\n        \u003Cmeta charset=\"utf-8\" \u002F>\n        \u003Cmeta name=\"viewport\" content=\"width=device-width, initial-scale=1\" \u002F>\n        \u003Ctitle>My App\u003C\u002Ftitle>\n      \u003C\u002Fhead>\n      \u003Cbody>\n        \u003CComponent \u002F>\n      \u003C\u002Fbody>\n    \u003C\u002Fhtml>\n  );\n}\n```\n\n**Async Server Components**\n```tsx\nexport default async function Page() {\n  const data = await fetchData(); \u002F\u002F Runs on server only\n  return \u003Cdiv>{data.title}\u003C\u002Fdiv>;\n}\n```\n\n## Data Fetching Patterns\n\nFresh 2.x provides two approaches for fetching data on the server. The handler pattern is the recommended default because it demonstrates the full Fresh 2.x architecture and provides the most flexibility.\n\n### Approach A: Handler with Data Object (Recommended)\n\nUse this as the default for data fetching. It uses the full Fresh 2.x handler pattern with typed data passing. Always show the complete setup including `utils\u002Fstate.ts` when demonstrating this pattern.\n\n```tsx\n\u002F\u002F utils\u002Fstate.ts - one-time setup for type-safe handlers\nimport { createDefine } from \"fresh\";\n\nexport interface State {\n  user?: { id: string; name: string };\n}\n\nexport const define = createDefine\u003CState>();\n```\n\n```tsx\n\u002F\u002F routes\u002Fposts.tsx\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\n\n\u002F\u002F Handler fetches data and returns it via { data: {...} }\nexport const handler = define.handlers(async (ctx) => {\n  const response = await fetch(\"https:\u002F\u002Fjsonplaceholder.typicode.com\u002Fposts\");\n  const posts = await response.json();\n  return { data: { posts } };\n});\n\n\u002F\u002F Page receives typed data\nexport default define.page\u003Ctypeof handler>(({ data }) => {\n  return (\n    \u003Cdiv>\n      \u003Ch1>Posts\u003C\u002Fh1>\n      \u003Cul>\n        {data.posts.map((post) => \u003Cli key={post.id}>{post.title}\u003C\u002Fli>)}\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n  );\n});\n```\n\nThis approach also supports auth checks, redirects, and other logic before rendering.\n\n### Approach B: Async Server Components (Shorthand)\n\nFor the simplest cases where you just need to fetch and display data with no auth or redirects:\n\n```tsx\n\u002F\u002F routes\u002Fservers.tsx\nexport default async function ServersPage() {\n  const servers = await db.query(\"SELECT * FROM servers\");\n\n  return (\n    \u003Cdiv>\n      \u003Ch1>Servers\u003C\u002Fh1>\n      \u003Cul>\n        {servers.map((s) => \u003Cli key={s.id}>{s.name}\u003C\u002Fli>)}\n      \u003C\u002Ful>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n### Decision Guide\n\n```\nNeed to fetch data on server?\n├─ Yes → Use handler with { data: {...} } return (Approach A)\n│   (supports auth checks, redirects, and typed data passing)\n├─ Simple DB query, no logic? → Async page component is also fine (Approach B)\n└─ No → Just use a regular page component\n```\n\n## Handlers and Define Helpers (Fresh 2.x)\n\nFresh 2.x uses a **single context parameter** pattern for handlers. Always use `(ctx)` as the only parameter.\n\n**Important:** When demonstrating any handler pattern (data fetching, form handling, API routes, auth), always show or reference the `utils\u002Fstate.ts` setup which imports `createDefine` from `\"fresh\"`. This ensures the complete Fresh 2.x architecture is visible.\n\n### Route Handlers\n\nAlways use `define.handlers()` for type-safe route handlers in file-based routes:\n\n```tsx\n\u002F\u002F routes\u002Fapi\u002Fusers.ts\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\n\n\u002F\u002F Single function handles all methods\nexport const handler = define.handlers((ctx) => {\n  return new Response(`Hello from ${ctx.req.method}`);\n});\n\n\u002F\u002F Or method-specific handlers\nexport const handler = define.handlers({\n  GET(ctx) {\n    return Response.json({ users: [] });\n  },\n  async POST(ctx) {\n    const body = await ctx.req.json();\n    return Response.json({ created: true }, { status: 201 });\n  },\n});\n```\n\nNote: Bare handler exports (`export const handler = (ctx) => {...}`) also work but lose TypeScript type safety. Prefer `define.handlers()`.\n\n### The Context Object\n\nThe `ctx` parameter provides everything you need:\n\n```tsx\nexport const handler = (ctx) => {\n  ctx.req          \u002F\u002F The Request object\n  ctx.url          \u002F\u002F URL instance with pathname, searchParams\n  ctx.params       \u002F\u002F Route parameters { slug: \"my-post\" }\n  ctx.state        \u002F\u002F Request-scoped data for middlewares\n  ctx.config       \u002F\u002F Fresh configuration\n  ctx.route        \u002F\u002F Matched route pattern\n  ctx.error        \u002F\u002F Caught error (on error pages)\n\n  \u002F\u002F Methods\n  ctx.render(\u003CJSX \u002F>)           \u002F\u002F Render JSX to Response (JSX only, NOT data objects!)\n  ctx.render(\u003CJSX \u002F>, { status: 201, headers: {...} })  \u002F\u002F With response options\n  ctx.redirect(\"\u002Fother\")        \u002F\u002F Redirect (302 default)\n  ctx.redirect(\"\u002Fother\", 301)   \u002F\u002F Permanent redirect\n  ctx.next()                    \u002F\u002F Call next middleware\n};\n```\n\n### Define Helpers (Type Safety)\n\nCreate a `utils\u002Fstate.ts` file for type-safe handlers:\n\n```tsx\n\u002F\u002F utils\u002Fstate.ts\nimport { createDefine } from \"fresh\";\n\n\u002F\u002F Define your app's state type\nexport interface State {\n  user?: { id: string; name: string };\n}\n\n\u002F\u002F Export typed define helpers\nexport const define = createDefine\u003CState>();\n```\n\nUse in routes:\n\n```tsx\n\u002F\u002F routes\u002Fprofile.tsx\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\nimport type { PageProps } from \"fresh\";\n\n\u002F\u002F Typed handler with data\nexport const handler = define.handlers((ctx) => {\n  if (!ctx.state.user) {\n    return ctx.redirect(\"\u002Flogin\");\n  }\n  return { data: { user: ctx.state.user } };\n});\n\n\u002F\u002F Page receives typed data\nexport default define.page\u003Ctypeof handler>(({ data }) => {\n  return \u003Ch1>Welcome, {data.user.name}!\u003C\u002Fh1>;\n});\n```\n\n### Middleware (Fresh 2.x)\n\n```tsx\n\u002F\u002F routes\u002F_middleware.ts\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\n\nexport const handler = define.middleware(async (ctx) => {\n  \u002F\u002F Before route handler\n  console.log(`${ctx.req.method} ${ctx.url.pathname}`);\n\n  \u002F\u002F Call next middleware\u002Froute\n  const response = await ctx.next();\n\n  \u002F\u002F After route handler\n  return response;\n});\n```\n\n### API Routes\n\n```tsx\n\u002F\u002F routes\u002Fapi\u002Fposts\u002F[id].ts\nimport { define } from \"@\u002Futils\u002Fstate.ts\";\nimport { HttpError } from \"fresh\";\n\nexport const handler = define.handlers({\n  async GET(ctx) {\n    const post = await getPost(ctx.params.id);\n    if (!post) {\n      throw new HttpError(404); \u002F\u002F Uses _error.tsx\n    }\n    return Response.json(post);\n  },\n\n  async DELETE(ctx) {\n    if (!ctx.state.user) {\n      throw new HttpError(401);\n    }\n    await deletePost(ctx.params.id);\n    return new Response(null, { status: 204 });\n  },\n});\n```\n\n## Islands (Interactive Components)\n\nIslands are components that get hydrated (made interactive) on the client. Place them in the `islands\u002F` folder or `(_islands)` folder within routes.\n\n### When to Use Islands\n\n- User interactions (clicks, form inputs)\n- Client-side state (counters, toggles)\n- Browser APIs (localStorage, geolocation)\n\n### Island Example\n\n```tsx\n\u002F\u002F islands\u002FCounter.tsx\nimport { useSignal } from \"@preact\u002Fsignals\";\n\nexport default function Counter() {\n  const count = useSignal(0);\n\n  return (\n    \u003Cdiv>\n      \u003Cp>Count: {count.value}\u003C\u002Fp>\n      \u003Cbutton onClick={() => count.value++}>\n        Increment\n      \u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n### Client-Only Code with IS_BROWSER\n\n```tsx\n\u002F\u002F islands\u002FLocalStorageCounter.tsx\nimport { IS_BROWSER } from \"fresh\u002Fruntime\";\nimport { useSignal } from \"@preact\u002Fsignals\";\n\nexport default function LocalStorageCounter() {\n  \u002F\u002F Return placeholder during SSR\n  if (!IS_BROWSER) {\n    return \u003Cdiv>Loading...\u003C\u002Fdiv>;\n  }\n\n  \u002F\u002F Client-only code\n  const stored = localStorage.getItem(\"count\");\n  const count = useSignal(stored ? parseInt(stored) : 0);\n\n  return (\n    \u003Cbutton onClick={() => {\n      count.value++;\n      localStorage.setItem(\"count\", String(count.value));\n    }}>\n      Count: {count.value}\n    \u003C\u002Fbutton>\n  );\n}\n```\n\n### Island Props (Serializable Types)\n\nIslands can receive these prop types:\n- Primitives: string, number, boolean, bigint, undefined, null\n- Special values: Infinity, -Infinity, NaN, -0\n- Collections: Array, Map, Set\n- Objects: Plain objects with string keys\n- Built-ins: URL, Date, RegExp, Uint8Array\n- Preact: JSX elements, Signals (with serializable values)\n- Circular references are supported\n\n**Functions cannot be passed as props.**\n\n### Island Rules\n\n1. **Props must be serializable** - No functions, only JSON-compatible data\n2. **Keep islands small** - Less JavaScript shipped to client\n3. **Prefer server components** - Only use islands when you need interactivity\n\n## Preact\n\nPreact is a 3KB alternative to React. Fresh uses Preact instead of React.\n\n### Preact vs React Differences\n\n| Preact | React |\n|--------|-------|\n| `class` works | `className` required |\n| `@preact\u002Fsignals` | `useState` |\n| 3KB bundle | ~40KB bundle |\n\n### Hooks (Same as React)\n\n```tsx\nimport { useState, useEffect, useRef } from \"preact\u002Fhooks\";\n\nfunction MyComponent() {\n  const [value, setValue] = useState(0);\n  const inputRef = useRef\u003CHTMLInputElement>(null);\n\n  useEffect(() => {\n    console.log(\"Component mounted\");\n  }, []);\n\n  return \u003Cinput ref={inputRef} value={value} \u002F>;\n}\n```\n\n### Signals (Preact's Reactive State)\n\nSignals are Preact's more efficient alternative to useState:\n\n```tsx\nimport { signal, computed } from \"@preact\u002Fsignals\";\n\nconst count = signal(0);\nconst doubled = computed(() => count.value * 2);\n\nfunction Counter() {\n  return (\n    \u003Cdiv>\n      \u003Cp>Count: {count}\u003C\u002Fp>\n      \u003Cp>Doubled: {doubled}\u003C\u002Fp>\n      \u003Cbutton onClick={() => count.value++}>+1\u003C\u002Fbutton>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\nBenefits of signals:\n- More granular updates (only re-renders what changed)\n- Can be defined outside components\n- Cleaner code for shared state\n\n## Tailwind CSS in Fresh (Optional)\n\nTailwind CSS is optional—you don't need it to build a great Fresh app. However, many developers prefer it for rapid styling. Fresh 2.x uses Vite for builds, so Tailwind integrates via the Vite plugin.\n\n### Setup\n\nInstall both Tailwind packages:\n\n```sh\ndeno add npm:@tailwindcss\u002Fvite npm:tailwindcss\n```\n\n**Important:** You need both packages. `@tailwindcss\u002Fvite` is the Vite plugin, and `tailwindcss` is the core library it depends on.\n\nConfigure Vite in `vite.config.ts`:\n```typescript\nimport { defineConfig } from \"vite\";\nimport tailwindcss from \"@tailwindcss\u002Fvite\";\n\nexport default defineConfig({\n  plugins: [tailwindcss()],\n});\n```\n\nAdd the Tailwind import to your CSS file (e.g., `assets\u002Fstyles.css`):\n```css\n@import \"tailwindcss\";\n```\n\nThen import this CSS file in your `client.ts`:\n```typescript\nimport \".\u002Fassets\u002Fstyles.css\";\n```\n\n### Usage\n\n```tsx\nexport default function Button({ children }) {\n  return (\n    \u003Cbutton class=\"px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600\">\n      {children}\n    \u003C\u002Fbutton>\n  );\n}\n```\n\n### Best Practices\n\n1. **Prefer utility classes** over `@apply`\n2. **Use `class` not `className`** (Preact supports both, but `class` is simpler)\n3. **Dark mode**: Use `class` strategy in tailwind.config.js\n\n```tsx\n\u003Cdiv class=\"bg-white dark:bg-gray-900\">\n  \u003Cp class=\"text-gray-900 dark:text-white\">Hello\u003C\u002Fp>\n\u003C\u002Fdiv>\n```\n\n## Building and Deploying\n\n### Development\n\n```bash\ndeno task dev      # Start dev server with hot reload (http:\u002F\u002F127.0.0.1:5173\u002F)\n```\n\n### Production Build\n\n```bash\ndeno task build    # Build for production\ndeno task preview  # Preview production build locally\n```\n\n### Deploy to Deno Deploy\n\n```bash\ndeno task build           # Build first\ndeno deploy --prod        # Deploy to production\n```\n\n## Quick Reference\n\n| Task | Command\u002FPattern |\n|------|-----------------|\n| Create Fresh project | `deno run -Ar jsr:@fresh\u002Finit` |\n| Start dev server | `deno task dev` (port 5173) |\n| Build for production | `deno task build` |\n| Add a page | Create `routes\u002Fpagename.tsx` |\n| Add an API route | Create `routes\u002Fapi\u002Fendpoint.ts` |\n| Add interactive component | Create `islands\u002FComponentName.tsx` |\n| Add static component | Create `components\u002FComponentName.tsx` |\n\n## Common Mistakes\n\n### Using Fresh 1.x Patterns (Most Common LLM Error)\n\n**Using old import specifiers**\n\nThe old dollar-sign Fresh import paths and alpha version imports are deprecated. Always use the stable `fresh` package:\n\n```tsx\n\u002F\u002F ✅ CORRECT - Fresh 2.x stable imports\nimport { App, staticFiles } from \"fresh\";\nimport type { PageProps } from \"fresh\";\n```\n\n**Using two-parameter handlers**\n\nThe old two-parameter handler signature is deprecated. Fresh 2.x uses a single context parameter:\n\n```tsx\n\u002F\u002F ✅ CORRECT - Fresh 2.x uses single context parameter\nexport const handler = {\n  GET(ctx) {  \u002F\u002F Single ctx param\n    return ctx.render(\u003CMyPage \u002F>);\n  }\n};\n```\n\n**Creating legacy files**\n\nFresh 2.x does not use a manifest file, a separate dev entry point, or a separate config file. The correct Fresh 2.x file structure is:\n\n```\nmain.ts           # Server entry\nclient.ts         # Client entry\nvite.config.ts    # Vite config\n```\n\n**Using deprecated context methods**\n\nThe old `renderNotFound()`, bare `render()` without JSX, and `basePath` patterns are deprecated. Use these Fresh 2.x patterns instead:\n\n```tsx\n\u002F\u002F ✅ CORRECT - Fresh 2.x patterns\nthrow new HttpError(404)\nctx.render(\u003CMyComponent \u002F>)\nctx.config.basePath\n```\n\n**Passing data from handlers to pages (VERY COMMON MISTAKE)**\n\nThis is a frequent error. In Fresh 2.x, you cannot pass data through `ctx.render()`. Instead, return an object with a `data` property from the handler:\n\n```tsx\n\u002F\u002F ✅ CORRECT - Return object with data property from handler\nexport const handler = define.handlers(async (ctx) => {\n  const servers = await getServers();\n  return { data: { servers } };  \u002F\u002F Return { data: {...} } object\n});\n\n\u002F\u002F ✅ CORRECT - Link page to handler type with typeof\nexport default define.page\u003Ctypeof handler>(({ data }) => {\n  return \u003Cul>{data.servers.map((s) => \u003Cli>{s.name}\u003C\u002Fli>)}\u003C\u002Ful>;\n});\n\n\u002F\u002F ✅ ALSO CORRECT - Use async page component (simpler when no auth\u002Fredirects needed)\nexport default async function ServersPage() {\n  const servers = await getServers();\n  return \u003Cul>{servers.map((s) => \u003Cli>{s.name}\u003C\u002Fli>)}\u003C\u002Ful>;\n}\n```\n\n**Old task commands in deno.json**\n\nThe old task commands that reference `dev.ts` are deprecated. Use the Vite-based tasks:\n\n```json\n\u002F\u002F ✅ CORRECT - Fresh 2.x tasks\n{\n  \"tasks\": {\n    \"dev\": \"vite\",\n    \"build\": \"vite build\",\n    \"preview\": \"deno serve -A _fresh\u002Fserver.js\"\n  }\n}\n```\n\n### Island Mistakes\n\n**Putting too much JavaScript in islands**\n```tsx\n\u002F\u002F ❌ Wrong - entire page as an island (ships all JS to client)\n\u002F\u002F islands\u002FHomePage.tsx\nexport default function HomePage() {\n  return (\n    \u003Cdiv>\n      \u003CHeader \u002F>\n      \u003CMainContent \u002F>\n      \u003CFooter \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n\n\u002F\u002F ✅ Correct - only interactive parts are islands\n\u002F\u002F routes\u002Findex.tsx (server component)\nimport Counter from \"..\u002Fislands\u002FCounter.tsx\";\n\nexport default function HomePage() {\n  return (\n    \u003Cdiv>\n      \u003CHeader \u002F>\n      \u003CMainContent \u002F>\n      \u003CCounter \u002F>\n      \u003CFooter \u002F>\n    \u003C\u002Fdiv>\n  );\n}\n```\n\n**Passing non-serializable props to islands**\n```tsx\n\u002F\u002F ❌ Wrong - functions can't be serialized\n\u003CCounter onUpdate={(val) => console.log(val)} \u002F>\n\n\u002F\u002F ✅ Correct - only pass JSON-serializable data\n\u003CCounter initialValue={5} label=\"Click count\" \u002F>\n```\n\n### Other Common Mistakes\n\n**Using `className` instead of `class`**\n```tsx\n\u002F\u002F ❌ Works but unnecessary in Preact\n\u003Cdiv className=\"container\">\n\n\u002F\u002F ✅ Preact supports native HTML attribute\n\u003Cdiv class=\"container\">\n```\n\n**Forgetting to build before deploying Fresh 2.x**\n```bash\n# ❌ Wrong - Fresh 2.x requires a build step\ndeno deploy --prod\n\n# ✅ Correct - build first, then deploy\ndeno task build\ndeno deploy --prod\n```\n\n**Creating islands for non-interactive content**\n```tsx\n\u002F\u002F ❌ Wrong - this doesn't need to be an island (no interactivity)\n\u002F\u002F islands\u002FStaticCard.tsx\nexport default function StaticCard({ title, body }) {\n  return \u003Cdiv class=\"card\">\u003Ch2>{title}\u003C\u002Fh2>\u003Cp>{body}\u003C\u002Fp>\u003C\u002Fdiv>;\n}\n\n\u002F\u002F ✅ Correct - use a regular component (no JS shipped)\n\u002F\u002F components\u002FStaticCard.tsx\nexport default function StaticCard({ title, body }) {\n  return \u003Cdiv class=\"card\">\u003Ch2>{title}\u003C\u002Fh2>\u003Cp>{body}\u003C\u002Fp>\u003C\u002Fdiv>;\n}\n```\n\n**Using old Tailwind plugin**\n\nThe old Fresh 1.x Tailwind plugin is deprecated. Fresh 2.x uses the Vite Tailwind plugin:\n\n```typescript\n\u002F\u002F ✅ CORRECT - Fresh 2.x uses Vite Tailwind plugin\nimport tailwindcss from \"@tailwindcss\u002Fvite\";\n```\n\n**Missing tailwindcss package**\n```sh\n# Error: Can't resolve 'tailwindcss' in '\u002Fpath\u002Fto\u002Fassets'\n\n# ❌ WRONG - Only installed the Vite plugin\ndeno add npm:@tailwindcss\u002Fvite\n\n# ✅ CORRECT - Install both packages\ndeno add npm:@tailwindcss\u002Fvite npm:tailwindcss\n```\n\nThe `@tailwindcss\u002Fvite` plugin requires the core `tailwindcss` package to be installed separately.\n\n## Fresh Alpha Versions (2.0.0-alpha.*)\n\nSome projects use Fresh 2.x alpha releases (e.g., `@fresh\u002Fcore@2.0.0-alpha.29`). These are **not Fresh 1.x** but use a different setup than stable Fresh 2.x:\n\n| Alpha pattern | Stable 2.x pattern |\n|---|---|\n| `dev.ts` entry point | `vite.config.ts` |\n| `@fresh\u002Fplugin-tailwind` | `@tailwindcss\u002Fvite` |\n| `deno run -A --watch dev.ts` | `vite` |\n| Dev server on port 8000 | Dev server on port 5173 |\n| No `client.ts` | Requires `client.ts` |\n| `deno run -A dev.ts build` | `vite build` |\n\n**IMPORTANT:** If you see `dev.ts` in a project with `@fresh\u002Fcore@2.0.0-alpha.*` in `deno.json`, do NOT treat it as a Fresh 1.x artifact. It is the correct entry point for alpha versions. Check the `deno.json` imports to determine which version is in use before suggesting changes.\n\nAlpha projects also use the handler pattern `define.handlers({ GET(ctx) { ... } })` which returns `{ data: {...} }` - this is the same as stable 2.x.\n\n## Migrating from Fresh 1.x to 2.x\n\nIf you have an existing Fresh 1.x project, run the migration tool:\n\n```bash\ndeno run -Ar jsr:@fresh\u002Fupdate\n```\n\nThis tool automatically:\n- Converts old import paths to the new `fresh` package\n- Updates handler signatures to use the single `(ctx)` parameter\n- Removes legacy generated and config files\n- Creates `vite.config.ts` and `client.ts`\n- Updates `deno.json` tasks to use Vite\n- Merges separate error pages into unified `_error.tsx`\n- Updates deprecated context method calls to Fresh 2.x equivalents\n\n### Manual Migration Checklist\n\nIf the tool misses anything:\n\n1. **Imports**: All Fresh imports should come from `fresh` or `fresh\u002Fruntime`\n2. **Handlers**: Should use single `(ctx)` parameter, access request via `ctx.req`\n3. **Files**: Remove any legacy generated files, dev entry points, or old config files\n4. **Tasks**: Update to `vite`, `vite build`, `deno serve -A _fresh\u002Fserver.js`\n5. **Error pages**: Use a single unified `_error.tsx`\n6. **Tailwind**: Use `@tailwindcss\u002Fvite` (the Vite plugin)\n",{"name":5,"license":15,"metadata":49,"description":7},{"author":50,"version":51},"denoland","2.4","master","c2e410e11df4d80d885e0ecf0583ef3c926df736","factory\u002Flibrary\u002Fskills\u002Fofficial_denoland_deno_frontend",0,"https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory","https:\u002F\u002Fgithub.com\u002FiDorgham","Dorgham.me","hey I'm Dorgham \r\nI code, I create, and AI codes back. \r\nMaybe we can give AI the chance!! now we begin. 🚀🤖\r\n... . . . git commit -m \"Hello, Future\" ","2026-05-04 18:39:09",{"source":8,"skillName":5,"commands":62,"prompt":72,"zipAvailable":73},[63,66,69],{"tool":64,"command":65},"npx","npx skills add iDorgham\u002FWorkspace-Factory --skill deno-frontend",{"tool":67,"command":68},"bunx","bunx skills add iDorgham\u002FWorkspace-Factory --skill deno-frontend",{"tool":70,"command":71},"pnpm","pnpm dlx skills add iDorgham\u002FWorkspace-Factory --skill deno-frontend","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Fskills\u002Fofficial_denoland_deno_frontend\u002Fskill.md",true,[],[76,102,124,145,164,187],{"skillNo":77,"name":78,"nameZh":6,"description":79,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":80,"categories":81,"keywords":83,"publishedAt":101},"01M71P8WVBMB2X3D24R0YT0B0E","vercel-react-view-transitions","Guide for implementing smooth, native-feeling animations using React's View Transition API (`\u003CViewTransition>` component, `addTransitionType`, and CSS view transition pseudo-elements). Use this skill whenever the user wants to add page transitions, animate route changes, create shared element animations, animate enter\u002Fexit of components, animate list reorder, implement directional (forward\u002Fback) navigation animations, or integrate view transitions in Next.js. Also use when the user mentions view transitions, `startViewTransition`, `ViewTransition`, transition types, or asks about animating between UI states in React without third-party animation libraries.","https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Fskills\u002Fofficial_vercel_labs_react_view_transitions\u002Fskill.md",[82],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[84,85,86,87,88,89,90,91,92,43,93,94,95,96,39,97,98,37,99,100],"react","vercel react view transitions","view","react view transitions","vercel","transitions","shared","back","Animation","types","states","element","implementing","components","api","create","libraries","2026-11-10 13:02:02",{"skillNo":103,"name":104,"nameZh":6,"description":105,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":106,"categories":107,"keywords":109,"publishedAt":101},"01M71P8TDGHZ289TSAC5VTG2EW","vercel-react-native-skills","React Native and Expo best practices for building performant mobile apps. Use when building React Native components, optimizing list performance, implementing animations, or working with native modules. Triggers on tasks involving React Native, Expo, mobile performance, or native platform APIs.","https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Fskills\u002Fofficial_vercel_labs_react_native_skills\u002Fskill.md",[108],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[84,110,111,88,112,113,114,115,96,116,39,117,97,118,119,120,121,122,123,30],"react native","native","vercel react native skills","react native skills","modules","performance","apps","tasks","mobile","expo","list","mobile performance","platform","animations",{"skillNo":125,"name":126,"nameZh":6,"description":127,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":128,"categories":129,"keywords":131,"publishedAt":101},"01M71P8QK4JF5BYRGYDDGPZQG9","vercel-react-best-practices","React and Next.js performance optimization guidelines from Vercel Engineering. This skill should be used when writing, reviewing, or refactoring React\u002FNext.js code to ensure optimal performance patterns. Triggers on tasks involving React components, Next.js pages, data fetching, bundle optimization, or performance improvements.","https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Fskills\u002Fofficial_vercel_labs_react_best_practices\u002Fskill.md",[130],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[84,132,133,88,134,115,135,39,136,117,97,137,138,139,140,141,34,142,143,144],"react best practices","vercel react best practices","best practices","writing","code","data fetching","react components","next","refactoring","data","Optimization","guidelines","triggers",{"skillNo":146,"name":147,"nameZh":6,"description":148,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":149,"categories":150,"keywords":152,"publishedAt":101},"01M71P8HVEA70K5N6ZVJCG2ED3","vercel-composition-patterns","React composition patterns that scale. Use when refactoring components with boolean prop proliferation, building flexible component libraries, or designing reusable APIs. Triggers on tasks involving compound components, render props, context providers, or component architecture. Includes React 19 API changes.","https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Fskills\u002Fofficial_vercel_labs_composition_patterns\u002Fskill.md",[151],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[153,88,154,34,155,156,157,158,144,159,160,29,39,161,117,97,162,163,98,84],"Composition","composition patterns","vercel composition patterns","react composition patterns","react 19","render","boolean","component architecture","reusable","architecture","react composition",{"skillNo":165,"name":166,"nameZh":6,"description":167,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":168,"categories":169,"keywords":173,"publishedAt":101},"01M71P60XXKKP222ZFJRG7R373","supabase-postgres-best-practices","Postgres performance optimization and best practices from Supabase. Use this skill when writing, reviewing, or optimizing Postgres queries, schema designs, or database configurations.","https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Fskills\u002Fofficial_supabase_supabase_postgres_best_practices\u002Fskill.md",[170],{"categoryNo":171,"categoryName":172,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000010","后端与接口",[174,175,176,177,134,178,179,180,30,142,115,181,182,135,183,29,184,185,186,39],"postgres best practices","supabase","postgres","supabase postgres best practices","categories","postgres performance","advanced","correct","schema","impact","Rules","critical","database",{"skillNo":188,"name":189,"nameZh":6,"description":190,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":191,"categories":192,"keywords":194,"publishedAt":44},"01M71P2ZCEJD0PKC458YTP1FJW","portable-text-serialization","Render and serialize Portable Text to React, Svelte, Vue, Astro, HTML, Markdown, and plain text. Use when implementing Portable Text rendering in any frontend framework, building custom serializers for non-standard block types, converting Portable Text to HTML strings server-side, converting Portable Text to Markdown, extracting plain text from Portable Text, or troubleshooting rendering issues with marks, blocks, lists, or custom types.","https:\u002F\u002Fgithub.com\u002FiDorgham\u002FWorkspace-Factory\u002Fblob\u002Fmaster\u002Ffactory\u002Flibrary\u002Fskills\u002Fofficial_sanity_io_portable_text_serialization\u002Fskill.md",[193],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},[195,196,197,198,199,93,200,158,201,96,24,202,39,84,203,204,205,206,207,208],"text","portable text serialization","portable","serialization","extracting","strings","issues","svelte","sanity","astro","server","markdown","rendering","vue"]