Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/hetari/creative-coding/llms.txt

Use this file to discover all available pages before exploring further.

The file src/config/sketches.ts exports a single typed SKETCHES: SketchMeta[] array that drives the entire Creative Coding playground. Every feature that needs to know about a sketch — the Vue Router route table, the dashboard card grid, the iframe/image preview toggle, and the nested category hierarchy — reads from this one array. Adding a sketch means adding one entry here; nothing else needs to be touched.

The SketchMeta Interface

Each entry in the SKETCHES array must conform to the SketchMeta interface. The full type definition is:
import type { Component } from 'vue'

export type PreviewMode = 'image' | 'iframe'

export interface SketchMeta {
  id: string
  title: string
  /** Slash-separated category path, e.g. 'shader', 'images', 'gsap/footer', 'gsap/loading' */
  category: string
  /** URL path without trailing slash, e.g. '/shader/learn', '/gsap/footer/ascii-hand' */
  path: string
  /** Sort key order (lower numbers come first) */
  order: number
  previewMode: PreviewMode
  resources?: string[]
  component: () => Promise<{ default: Component }>
}

Field Reference

id
string
required
A unique, kebab-case identifier for the sketch. Used as a stable key throughout the application — for example, as a Vue key attribute when rendering card lists. The convention is to join the full category path and sketch name with hyphens, e.g. 'gsap-footer-ascii-hand'.
title
string
required
The human-readable display name shown on the dashboard card and in the page title. This value is used directly — no slug transformation is applied. Example: 'Ascii Hand', 'Reveal Loader'.
category
string
required
A slash-separated path that places the sketch within the category hierarchy. A single segment (e.g. 'shader') means the sketch lives directly under a top-level category. Multiple segments (e.g. 'gsap/footer') create nested sub-categories. The dashboard uses this field to build its folder structure — each unique segment becomes either a folder card or a leaf card depending on depth.
path
string
required
The full URL path that Vue Router registers for this sketch, without a trailing slash. Must begin with / and should mirror the category hierarchy, e.g. '/gsap/footer/ascii-hand'. This value is also used by getSketchByPath() to resolve the active sketch from the current URL.
order
number
required
A numeric sort key controlling the order in which sketches and categories appear on the dashboard. Lower numbers are listed first. The recommended convention is to use multiples of 10 (0, 10, 20, 30, …) so that future sketches can be inserted between existing ones without renumbering.
previewMode
"image" | "iframe"
required
Controls how the sketch is previewed on the dashboard card. 'iframe' embeds the live sketch route in a sandboxed <iframe>. 'image' shows a static screenshot instead. Currently all registered sketches use 'iframe'.
resources
string[]
An optional array of external URLs — tutorials, reference videos, or inspiration links — associated with the sketch. These are surfaced on the dashboard card so contributors can find the original source material. Example: ['https://www.youtube.com/@codingmath/videos'].
component
() => Promise<{ default: Component }>
required
A dynamic import factory that lazy-loads the sketch’s root Vue component. Vite uses this to split each sketch into its own chunk, keeping the initial bundle small. Always point to an index.vue file inside the sketch’s directory, using the @/ alias for src/. Example: () => import('@/sketches/gsap/footer/ascii-hand/index.vue').

The Current SKETCHES Array

The following is the complete SKETCHES array as it exists in the repository today. This is the real data powering all routing and dashboard rendering:
export const SKETCHES: SketchMeta[] = [
  {
    id: 'shader-learn',
    title: 'Learn',
    category: 'shader',
    path: '/shader/learn',
    order: 0,
    previewMode: 'iframe',
    component: () => import('@/sketches/shader/learn/index.vue'),
  },
  {
    id: 'images-swiper',
    title: 'Swiper',
    category: 'images',
    path: '/images/swiper',
    order: 10,
    previewMode: 'iframe',
    resources: ['https://www.youtube.com/@codingmath/videos'],
    component: () => import('@/sketches/images/swiper/index.vue'),
  },
  {
    id: 'gsap-footer-ascii-hand',
    title: 'Ascii Hand',
    category: 'gsap/footer',
    path: '/gsap/footer/ascii-hand',
    order: 20,
    previewMode: 'iframe',
    component: () => import('@/sketches/gsap/footer/ascii-hand/index.vue'),
  },
  {
    id: 'gsap-loading-reveal-loader',
    title: 'Reveal Loader',
    category: 'gsap/loading',
    path: '/gsap/loading/reveal-loader',
    order: 30,
    previewMode: 'iframe',
    component: () => import('@/sketches/gsap/loading/reveal-loader/index.vue'),
  },
]

Helper Functions

src/config/sketches.ts also exports two utility functions that the router and dashboard components use to reason about paths at runtime.

getSketchByPath()

export function getSketchByPath(path: string): SketchMeta | undefined
Searches the SKETCHES array for an entry whose path exactly matches the given string. Trailing slashes are normalised before comparison — '/shader/learn/' and '/shader/learn' both resolve to the same sketch. Returns undefined if no match is found, which signals to the router that the current path is a category dashboard rather than a leaf sketch. Example:
getSketchByPath('/gsap/footer/ascii-hand')
// → { id: 'gsap-footer-ascii-hand', title: 'Ascii Hand', … }

getSketchByPath('/gsap')
// → undefined  (this is a category, not a leaf sketch)

isCategoryPath()

export function isCategoryPath(path: string): boolean
Returns true when the given path prefix matches the category field of at least one sketch — either as an exact match or as the beginning of a deeper category path. Leading and trailing slashes are stripped before comparison. This function is used to distinguish valid category dashboard routes from unknown paths. Example:
isCategoryPath('/gsap')         // → true  ('gsap/footer' and 'gsap/loading' both start with 'gsap')
isCategoryPath('/gsap/footer')  // → true  ('gsap/footer' is an exact category match)
isCategoryPath('/gsap/footer/ascii-hand') // → false  (this is a leaf sketch path, not a category)
isCategoryPath('/unknown')      // → false

Order Convention

Use multiples of 10 when assigning order values: 0, 10, 20, 30, …. This leaves nine integer slots between any two adjacent entries, so you can insert a new sketch between existing ones by choosing a value like 5 or 15 without having to renumber every subsequent entry.
Order only affects display order within a shared parent category. Sketches in different top-level categories are always sorted independently.
To add a new sketch, add one entry to the SKETCHES array and create the corresponding index.vue component file at the matching path inside src/sketches/. No route files need editing, no dashboard components need updating — the array is the only registration step.

Build docs developers (and LLMs) love