README.md

June 17, 2026 ยท View on GitHub

ILUMINATY Logo ILUMINATY

Professional Vue 3 template for editorial and commercial websites. It includes a blog, app download landing page, profile directory, event promotion, Sanity-ready content and forms ready to connect to Brevo, Mailchimp or any custom backend through webhooks.

Use cases: music platforms, creator directories, editorial websites, event promotion, app launches, creator communities, sports directories, conference sites, startup landing pages and commercial websites powered by a headless CMS.

ILUMINATY template preview

Live demo License Apache 2.0 Follow LuynoxRD

Vue 3 Vite TypeScript Tailwind CSS GSAP Sanity

If this project helps you, consider leaving a star on the repository.

Overview

ILUMINATY is a reusable Vue 3 template designed to ship a polished marketing site plus editorial infrastructure without coupling the frontend to one author account or one CMS instance.

This repository is intentionally delivered in two modes:

  • local: instant demo mode with seeded content and images so the site works immediately after clone
  • sanity: headless CMS mode using the Sanity adapter already wired in the frontend

The current demo is music-focused, but the architecture is generic. The artist model acts as a directory entry model and can be repurposed for creators, athletes, speakers, founders, teams, products or any other profile-based catalog.

Production Scope

ILUMINATY is ready for production as an SSG template for small to medium editorial sites, landing pages and catalogs.

Operational reality:

  • the Sanity integration now fetches large post and event collections in build-time batches using cursor pagination, which avoids oversized single requests and reduces timeout risk during extraction
  • the final SSG build still assembles one complete content snapshot in Node.js memory before pages are rendered
  • because of that, this template should be treated as a static-site solution for small to medium volumes, not as an infinite-scale publishing architecture

Practical guidance:

  • for most template use cases, this architecture is the correct tradeoff
  • once a project approaches six-figure content volumes such as roughly 100,000 posts, events or equivalent route-producing records, reevaluate the architecture instead of assuming SSG will remain comfortable
  • the exact ceiling is not guaranteed and depends on content size, route count, build machine RAM and Node.js heap settings
  • beyond that range, migrate to a server-rendered or hybrid model that can render pages on demand instead of materializing the full site during build

Delivery caveats:

  • validate the Sanity integration against a real Sanity project and real content before launch
  • form security and delivery guarantees depend on the real backend or webhook implementation you connect
  • transitive dependency risk depends on the state of upstream packages in your install graph

Why Sanity

Sanity is the default CMS in this repository because it solves the hard parts of content operations cleanly:

  • structured documents instead of freeform page blobs
  • editor-friendly Studio for non-developers
  • image hosting and transformations
  • flexible schemas for directory entries, events, blog posts and legal pages
  • an API model that maps well to a typed Vue application

If the final client is not technical, Sanity is the correct path in this repository because the adapter, document mapping and frontend integration are already implemented. Before production launch, validate the final setup against the real Sanity project and content model you will ship.

Stack

TechnologyWhy it is used
Vue 3Component architecture and reactive UI.
Vite 8Fast dev server and lean production builds.
Vite SSGStatic generation for marketing pages and blog routes.
TypeScriptStrong contracts across views, adapters, schemas and services.
Tailwind CSSFast, consistent utility-first styling.
Custom CSSBrand-specific presentation that should not be forced into utility classes.
Vue RouterMarketing routes plus dynamic blog routes.
UnheadSEO meta tags and page head management.
GSAPMotion for hero sections and visual transitions.
ZodRuntime validation for content snapshots and form payloads.
DOMPurifySanitization before form payloads leave the browser.
SanityHeadless CMS adapter already wired.

Quick Start

Requirements

  • Node.js 20+ recommended
  • npm 10+ recommended

Install and run

npm install
npm run dev

Quality checks

npm run lint
npx vue-tsc --noEmit

npm run lint validates the codebase without mutating files. Use npm run lint:fix when you want ESLint to apply safe autofixes.

Linting is configured with the modern flat ESLint setup in eslint.config.js.

This template ships with Vitest. Run the test suite with:

npm run test        # watch mode
npm run test:run    # single pass
npm run test:coverage

Production build

npm run build

The build runs two steps:

  1. scripts/generate-sitemap.mjs generates public/sitemap.xml and public/robots.txt
  2. vite-ssg build renders the static application and blog routes

Deploy

The output of npm run build is a static directory at dist/. Any static host works.

GitHub Pages

The repository ships with a ready-to-use workflow at .github/workflows/deploy.yml. Set VITE_SITE_URL as a repository secret or variable, push to main, and the site deploys automatically. The demo at luynoxrd.github.io/ILUMINATY is deployed this way.

If the site lives under a subpath (for example https://username.github.io/repo-name/), set VITE_SITE_URL to the full URL including the subpath. The build derives the Vite base automatically from that value.

Netlify

# netlify.toml
[build]
  command = "npm run build"
  publish = "dist"

Set VITE_SITE_URL and any other variables in the Netlify dashboard under Site settings โ†’ Environment variables.

Vercel

// vercel.json
{
  "buildCommand": "npm run build",
  "outputDirectory": "dist"
}

Set VITE_SITE_URL and other variables in the Vercel dashboard under Project settings โ†’ Environment variables.

Cloudflare Pages

Connect the repository in the Cloudflare dashboard and set:

SettingValue
Build commandnpm run build
Build output directorydist

Set VITE_SITE_URL and other variables under Settings โ†’ Environment variables.

Environment Variables

Copy .env.example into .env and set the values you need.

Core variables:

VariablePurpose
VITE_SITE_URLCanonical site URL used by the frontend, SEO metadata and build base path. Include the subpath if the site is deployed under one, for example https://example.com/portfolio.
VITE_CONTENT_SOURCElocal or sanity.
VITE_SANITY_PROJECT_IDSanity project id.
VITE_SANITY_DATASETSanity dataset name.
VITE_SANITY_API_VERSIONSanity API version.
VITE_SANITY_USE_CDNEnables or disables Sanity CDN reads.
VITE_FORM_PROVIDERmock, webhook or custom for contact form submissions.
VITE_FORM_ENDPOINTServer endpoint for the contact form.
VITE_NEWSLETTER_PROVIDERmock, webhook or custom for newsletter and event alerts.
VITE_NEWSLETTER_ENDPOINTServer endpoint for newsletter and event alerts.

Important security rule: never expose private API keys in VITE_* variables. Secrets belong in a backend, serverless function or HttpOnly session flow, not in the browser bundle.

Deployment note: the Vite base path is derived automatically from VITE_SITE_URL. If the site lives at the domain root, use https://example.com. If it lives under a subdirectory, include that subdirectory in VITE_SITE_URL.

Theme Modes

The site includes three theme modes:

  • light
  • dark
  • system

The selected mode is stored in localStorage under the iluminaty-theme key.

Behavior:

  • first visit defaults to system
  • system follows the operating system preference
  • if the user manually selects light or dark, that preference persists across sessions until the user selects system again
  • public/theme-init.js is loaded by index.html before Vue mounts and applies the right theme immediately, preventing any flash of the wrong theme

Demo Mode vs CMS Mode

Local mode

This is the default mode for first-run preview and template evaluation.

Content is read from:

  • src/data/pageContent.ts
  • src/data/artists.ts
  • src/data/events.ts
  • src/data/blogPosts.ts
  • src/data/about.ts
  • src/data/followers.ts
  • src/data/assets.ts

Sanity mode

When VITE_CONTENT_SOURCE=sanity, the frontend loads content through:

  • src/services/content/sanityAdapter.ts
  • src/services/content/index.ts
  • src/composables/useContent.ts
  • src/types/content.ts
  • src/schemas/content.ts

Implementation notes:

  • the adapter validates the normalized content snapshot with Zod before the app mounts
  • loadContent() resolves before Vue mounts, so components do not boot against an unresolved remote snapshot
  • large post and event collections are fetched in build-time batches using cursor pagination by _id, then sorted in memory for the final snapshot
  • the sitemap generator follows the same source selection and uses the same Sanity mode during build

The Sanity adapter already powers:

  • home page
  • about page
  • contact page
  • directory page
  • events page
  • blog page and blog posts
  • terms page
  • privacy page
  • cookies page
  • footer and site settings
  • featured directory entries on the home page

Sanity Setup

1. Create or open your Sanity project

npm create sanity@latest

2. Copy the schemas from this repository

Use the schemas inside:

  • sanity-template/schemaTypes/documents/
  • sanity-template/schemaTypes/index.ts

3. Configure the frontend

Set your .env:

VITE_SITE_URL=https://your-domain.com
VITE_CONTENT_SOURCE=sanity
VITE_SANITY_PROJECT_ID=your_project_id
VITE_SANITY_DATASET=production
VITE_SANITY_API_VERSION=2025-01-01
VITE_SANITY_USE_CDN=true

4. Run the frontend

npm run dev

5. Build static pages

npm run build

Blog routes are generated from the available posts during the build. In sanity mode, post discovery for the sitemap and route generation uses batched extraction instead of a fixed hard limit.

Sanity Document Map

Populate these documents to reflect content across the frontend.

Global site settings

Document: siteSettings

Fill:

  • brandName
  • footerDescription
  • footerLinkGroups
  • footerFollowLabel
  • footerCopyright
  • footerCreditPrefix
  • footerCreditName
  • footerCreditHref
  • footerCreditConnector
  • footerTechnologyName
  • footerTechnologyHref
  • footerRepositoryLink
  • socialProfiles

This document controls the footer, social links and attribution area, including the View Repository button and the Powered by LuynoxRD and Vue.js credit line. Replace or remove those values in your fork before publishing your version.

Home page

Document: homePage

Fill:

  • hero
  • appPreview
  • labelsSection
  • highlightCard
  • featuredArtistsSection
  • communitySection
  • faqSection
  • featuredBlogSection
  • newsletterSection
  • appCta

Home also uses:

  • brandLogo documents for label or partner logos
  • featured directory entries from the artist collection
  • the latest blog posts from the post collection

About page

Document: aboutPage

Fill the hero, mission, values, team intro and manifesto content. Team members themselves are loaded from teamMember documents.

Contact page

Document: contactPage

Fill the contact hero, method blocks, FAQ section and call-to-action copy. The contact form itself is powered by the form provider layer described later in this README.

Directory page

Document: artistsPage

Even though the schema name is artistsPage, treat it as the directory page configuration for any profile-based catalog.

Fill:

  • heroTitle
  • heroDescription
  • filters
  • genreOptions
  • neighborhoodOptions
  • resultsSection
  • actions
  • popup
  • emptyState

The popup labels for music and social links are also controlled from this document.

Directory entries

Collection: artist

Each document controls one directory profile. Fill:

  • name
  • genre
  • bio
  • locationLabel
  • image
  • homeImage
  • neighborhoods
  • badge
  • featured
  • links.spotify
  • links.youtube
  • links.appleMusic
  • links.instagram
  • links.tiktok
  • links.x
  • links.soundcloud

How featured entries work on the home page:

  • set featured: true on the profiles you want to surface
  • the frontend reads only featured items
  • the home section is capped at 10 entries
  • if no featured entries exist in Sanity, the template falls back to local demo entries

Events page

Document: eventsPage

Fill:

  • heroTitle
  • heroDescription
  • statsLabels
  • filters
  • resultsSubtitle
  • resultsTitleSuffix
  • emptyState
  • purchaseStepsTitle
  • purchaseSteps
  • notificationSection
  • cardLabels

Event collection

Collection: event

Each event controls:

  • title
  • description
  • date
  • time
  • doorsOpen
  • venue
  • price
  • artists
  • isSoldOut
  • image
  • ticketUrl

Frontend behavior:

  • if ticketUrl exists and isSoldOut is false, the event is shown as available and the CTA opens the purchase page
  • if isSoldOut is true, the event is rendered as sold out even if a URL exists
  • if ticketUrl is empty and isSoldOut is false, the event is rendered as coming soon
  • month and venue filters are automatic
  • counters are derived from the event collection and keep available, sold out and not-yet-ticketed states separate

Blog page

Document: blogPage

Fill:

  • heroTitle
  • heroDescription
  • newsletterSection
  • post.backLabel
  • post.shareLabel
  • post.authorLabel
  • post.tocLabel
  • post.relatedEyebrow
  • post.relatedTitle
  • post.relatedLinkLabel
  • post.newsletterEyebrow
  • post.newsletterTitle
  • post.newsletterDescription

Blog posts

Collection: post

Each post controls:

  • title
  • slug
  • excerpt
  • metaDescription
  • category
  • date
  • author
  • authorBio
  • imageAlt
  • readTime
  • coverImage
  • tags
  • contentBlocks

Supported content blocks:

  • heading
  • paragraph
  • bullet list
  • quote
  • image block
  • embed

Documents:

  • termsPage
  • privacyPage
  • cookiesPage

Each legal page can be edited from Sanity through:

  • heroTitle
  • heroDescription
  • sections
  • contactCard
  • footerNote
  • ctaTitle
  • ctaDescription
  • ctaLink

How Content Updates Flow to the Site

The frontend consumes one normalized content snapshot. That means all pages read data from a single typed contract, whether the source is local seed data or Sanity.

The flow is:

  1. Sanity documents are queried in src/services/content/sanityAdapter.ts
  2. The adapter maps raw CMS data into the frontend contracts defined in src/types/content.ts
  3. Zod validates the final snapshot through src/schemas/content.ts
  4. Vue views read the content through useContent()

For large collections, the adapter fetches post and event documents in batches using cursor pagination rather than a single unbounded query.

Why this matters:

  • editors can update copy without touching Vue files
  • the frontend stays strongly typed
  • switching between local demo content and Sanity does not require rewriting components

Images

This template has two image pipelines.

1. Local demo images

Used in local mode and as fallback data.

Managed through:

  • src/assets/
  • public/data/
  • src/data/assets.ts

This includes:

  • directory entry demo images
  • event demo images
  • blog demo covers
  • about and team images
  • follower and testimonial images
  • phone mockup
  • default partner logos

2. Sanity images

Used in sanity mode for editorial content.

The adapter already resolves Sanity image fields to plain URLs for:

  • home app preview
  • brand logos
  • directory entry images
  • featured home images
  • event images
  • blog cover images
  • about and team media

If you want every visible image to come from Sanity, upload and fill the corresponding image fields in the mapped documents instead of relying on local fallback assets.

How to Move from Local Content to Full Sanity Content

If you want the site to be fully driven by Sanity instead of demo seed data:

  1. Keep the template in local mode while you customize layout and branding
  2. Create and register the Sanity Studio schemas from sanity-template/
  3. Populate all singleton documents:
    • siteSettings
    • homePage
    • aboutPage
    • contactPage
    • artistsPage
    • eventsPage
    • blogPage
    • termsPage
    • privacyPage
    • cookiesPage
  4. Populate all collections:
    • artist
    • event
    • post
    • teamMember
    • testimonial
    • brandLogo
  5. Switch .env to VITE_CONTENT_SOURCE=sanity
  6. Run npm run dev and verify each route
  7. Run npx vue-tsc --noEmit and npm run build

The local seed can remain in the repository as demo fallback for future template users. You do not need to delete it unless you want a Sanity-only codebase.

Forms: Brevo, Mailchimp or Any Backend

This frontend does not send requests directly to Brevo or Mailchimp from the browser, because that would introduce avoidable security vulnerabilities and expose sensitive integration details in the client.

Instead, the project ships a provider layer that supports:

  • mock
  • webhook
  • custom

Relevant files:

  • src/config/forms.ts
  • src/services/forms/index.ts
  • src/types/forms.ts
  • src/schemas/forms.ts

Existing form surfaces:

  • contact form
  • blog newsletter
  • home newsletter
  • event alerts newsletter

Recommended production setup:

  1. Frontend submits to your backend or serverless function
  2. Backend stores the private API key
  3. Backend forwards the payload to Brevo, Mailchimp or any internal CRM
  4. Frontend receives a safe success or error response

Client-side sanitization in this template is a hygiene measure, not a trust boundary. The receiving backend must still validate, sanitize and safely persist or forward every payload.

Example:

VITE_FORM_PROVIDER=webhook
VITE_FORM_ENDPOINT=https://your-api.com/forms/contact

VITE_NEWSLETTER_PROVIDER=webhook
VITE_NEWSLETTER_ENDPOINT=https://your-api.com/forms/newsletter

Extending the CMS Layer

Sanity is the production-ready CMS integration included in this repository.

The content layer is adapter-based, so other CMS providers can be added later by implementing the same ContentAdapter contract used by the local and Sanity sources.

If your client needs a non-technical editing workflow today, keep Sanity. It is the only fully wired CMS integration in this template at the moment.

Security Maintenance

This repository includes a baseline security maintenance setup for a public frontend project:

  • SECURITY.md documents the reporting and maintenance posture
  • .github/dependabot.yml enables scheduled dependency update pull requests
  • .github/workflows/gitleaks.yml runs secret scanning on pull requests, pushes to main and a weekly schedule
  • gitleaks.toml extends the default Gitleaks ruleset used locally and in CI
  • GitHub Dependabot alerts and security updates can be enabled in repository settings
  • the current lint stack uses modern ESLint flat config and the build toolchain has been updated to patched dependency ranges

Recommended recurring checks:

  • npm audit
  • npm outdated
  • npm run lint
  • npx vue-tsc --noEmit
  • npm run build
  • gitleaks dir .
  • gitleaks git .

Publishing Checklist for Your Fork

  • replace demo branding, copy and media
  • update VITE_SITE_URL
  • populate your Sanity project if you want CMS mode
  • validate the real Sanity project end to end before launch
  • connect your form endpoints
  • replace or remove the footer View Repository button
  • replace or remove the footer Powered by LuynoxRD and Vue.js credit line
  • review siteSettings.socialProfiles
  • confirm featured directory entries on the home page
  • run npm run lint
  • run npx vue-tsc --noEmit
  • run npm run build
  • run gitleaks dir . and gitleaks git . if you have Gitleaks installed locally
  • review Dependabot and code scanning alerts before each release
  • add automated tests if your delivery process requires regression coverage

Project Structure

src/
  components/        reusable UI blocks
  composables/       content, forms and theme logic
  config/            runtime source and provider selection
  data/              local demo content
  lib/               shared helpers
  schemas/           Zod validators
  services/          CMS and form adapters
  types/             shared frontend contracts
  views/             route-level pages

sanity-template/
  schemaTypes/       ready-to-use Sanity schemas

License

Apache 2.0. See LICENSE and NOTICE.

This repository is open source and permits reuse, modification and commercial use under Apache License 2.0.

Practical effect:

  • redistributed versions must preserve the license and applicable notices
  • modified files should be marked as changed when redistributed
  • attribution notices in NOTICE must travel with qualifying redistributions
  • the ILUMINATY name, logo and branding are not granted for trademark use beyond reasonable attribution of origin

Important: Apache 2.0 helps preserve authorship and notices, but it does not prohibit commercial use, resale, forks or large-scale redistribution by itself. If someone wants white-label or OEM-style commercial terms beyond the open source license, contact the author separately.

Made with love by LuynoxRD and Vue.js ๐Ÿ’š