Docs

Tech Stack

The technical stack and architecture decisions for CraftlyNow.

Tech Stack

Core stack

LayerTechnologyPurpose
FrontendNuxt.js + Nuxt UIApp framework and UI components
Backend / DBSupabaseDatabase, auth, storage, API
HostingVercelDeployment and edge functions
EditorTipTapRich text editing for video descriptions

Supabase

Supabase handles everything on the backend:

  • Auth — user sign-in and session management
  • Database — courses, videos, transcripts, metadata
  • Storage — any assets attached to courses
  • RLS — row-level security ensures users only manage their own courses

Core tables

courses

id              uuid primary key
user_id         uuid references auth.users
title           text
description     text
is_published    boolean default false
share_token     text unique
created_at      timestamptz

course_videos

id              uuid primary key
course_id       uuid references courses
youtube_url     text
youtube_title   text
youtube_thumb   text
youtube_desc    text
transcript      text
notes           text  -- TipTap JSON or HTML
position        integer
created_at      timestamptz

YouTube data layer

YouTube metadata and transcripts are pulled server-side to avoid CORS issues and to keep API keys off the client.

Metadata pull (YouTube oEmbed / Data API):

  • Title
  • Thumbnail
  • Description
  • Channel name

Transcript pull:

  • Uses the YouTube transcript API (unofficial) or a Supabase edge function
  • If no transcript is available, the field is set to null
  • Transcript is stored once and not re-fetched

TipTap editor

TipTap is used for the per-video description / notes field.

  • Renders as a rich text editor for authenticated users
  • Renders as read-only formatted content for viewers
  • AI generation writes into TipTap's content format
  • Supports text, headings, bullet lists, bold, italic as a minimum

AI summary generation

The AI summary is generated from the stored transcript using a server-side API call.

  • Triggered manually by the user (not automatic on save)
  • Output is written into the TipTap description field
  • The user can edit, regenerate, or ignore the AI output
  • No AI generation if transcript is null

Sharing architecture

Each course has a share_token — a unique random string generated on creation.

  • Private share URL: /c/[share_token]
  • Public URL: /courses/[id] or /courses/[slug] — only active when is_published = true

Public courses appear on the landing page via a Supabase query filtered to is_published = true.