- JavaScript 86.1%
- SCSS 5.8%
- HTML 4.7%
- XSLT 2.9%
- TypeScript 0.3%
- Other 0.1%
| Filename | Latest commit message | Latest commit date |
|---|---|---|
|
|
||
| .claude/agents | ||
| .forgejo/workflows | ||
| .github | ||
| .zed | ||
| bin | ||
| packages/js-toolkit | ||
| screenshots | ||
| scripts | ||
| src | ||
| test | ||
| .claude.json | ||
| .codex | ||
| .eleventy.js | ||
| .envrc | ||
| .gitignore | ||
| .jscpd.json | ||
| .pages.yml | ||
| .stylelintrc.json | ||
| biome.json | ||
| BLOCKS_LAYOUT.md | ||
| bun.lock | ||
| bunfig.toml | ||
| CLAUDE.md | ||
| flake.lock | ||
| flake.nix | ||
| knip.json | ||
| LICENSE | ||
| package.json | ||
| README.md | ||
| tsconfig.json | ||
| tsconfig.strict.json | ||
The Chobble Template
⚠️ Don't forget to change the Formspark and Botpoison info in _data/config.json or in your repository's action secrets ⚠️
See this template in action at:
- example.chobble.com
- tradesperson-example.chobble.com
- southportorganics.co.uk
- house-of-desserts.co.uk
- ukegroupnorth.com
- myalarmsecurity.co.uk
- c-results.uk
- playsafeplayinspection.co.uk
- garsdalecottages.co.uk
- medwaymascots.co.uk
- funprouk.co.uk
Want me to make you a website based on this template? Hit me up at chobble.com.
💖 Want to support the development of this template? 💖 Donate at liberapay.com/chobble
An Eleventy starter for business websites. The GitHub action deploys to both Neocities and Bunny.net - you'll need to edit that for your setup.
Content Types
- Products - galleries, options with SKUs, FAQs, specifications, features lists, linked reviews with ratings
- Categories - product groupings with inherited thumbnails
- Events - one-off and recurring schedules, iCal feed generation
- News - blog posts with Atom feed
- Menus - categories, items, pricing, dietary indicators (vegan, gluten-free, etc.)
- Locations - multi-site support with sub-locations
- Properties - for holiday lets, linked to locations
- Reviews - linked to products, aggregate ratings
- Team - member profiles
- Snippets - reusable content blocks
Shopping Cart & Payments
- LocalStorage-based cart with quantity limits
- Stripe/Square checkout via external ecommerce backend
- Quote/enquiry mode (submit cart as request instead of payment)
- Auto-generated SKUs via GitHub Action
Theming
- 10 pre-built themes: Default, Neon, 90s Computer, Floral, Hacker, Monochrome, Ocean, Old Mac, Rainbow, Sunset
- Per-page theme overrides
- Visual theme editor at
/theme-editor/with export - CSS custom properties for colours, fonts, borders, layout
- SCSS support
- Bunny Fonts integration
Images
- Responsive images with
srcsetviaeleventy-img - Base64 LQIP placeholders
- Gallery component with thumbnail navigation and full-size overlay
- Custom aspect ratio cropping
Forms
SEO & Structured Data
- Schema.org markup for products (with reviews/ratings), events, FAQs, organisation
- Canonical URLs
- Sitemap
- Atom feed with XSL stylesheet
- Meta descriptions, noindex support
- hreflang tags and
og:localefor sites published in more than one language
Languages
A site is written in one language until it says otherwise, and nothing in the template names a language.
_data/languages.jsonlists every language the site publishes, each with acode,hreflang,og_locale,label,home_urlprefix,home_labelandbreadcrumb_label. Exactly one entry hasis_default: true, which is the base language: the one every URL outside another language's prefix is written in, and the onehreflang="x-default"points at._data/translations.jsonpairs the pages that say the same thing, keyed by language code, e.g.[{ "en": "/about/", "de": "/de/ueber-uns/" }].
A page's language comes from its URL prefix, and the layout, the head tags, the
footer switcher and the breadcrumbs read it as pageLanguage. Exactly one
language must be marked is_default, and a site that marks none fails the
build. To add a language, add its entry,
put its pages under its home_url, list them in translations.json, and
translate _includes/footer.html and the navigation for it. A page with no
counterpart in a language links that language's home page from the footer.
The template ships one language and no translations, which renders exactly as it did before this existed: no hreflang tags and no switcher.
What is translated is pages. Collection items (products, events, categories,
properties, guide categories) have no language of their own: they are looked up
by slug across the whole collection, and their labels come from
_data/strings.json, which has no language dimension. A translated page that
sits under a collection gets its index URL from the translation groups where a
site has paired one, but the crumb's label, and any category or property crumb
below it, still come from the base language. Translating a collection needs a
language on its items and per-language strings, which is its own change.
Navigation & Layout
- Horizontal or left sidebar navigation
- Sticky mobile nav option
- Two-column layout with sidebar
- Slider component for horizontal scrolling
- Scroll-fade animations (respects
prefers-reduced-motion)
Development
- Nix flakes with direnv support
bin/lint- format with Biomebin/screenshot- automated screenshots- Biome linting
- jscpd duplicate detection
- Knip unused code detection
- 17+ test files with custom runner
- instant.page for link prefetching on hover
Testing template code in a downstream client site
Sites built from this template copy it excluding test/, test-*, images/,
and markdown content, then overlay their own site content under src/. That
missing test/ directory means the suite can't run at all from a checkout in
that state, and even with it copied back in by hand, fixture-driven tests
fail, because the test fixture factory (test/test-site-factory.js) builds
its "template defaults" (config, sample content) from the live checkout
root — which is now your own site content, not the template's.
scripts/stage-hermetic-tests.js handles both problems for you. Point it at
a separate, pristine template checkout and it creates a temporary workspace
containing your downstream template code plus pristine template tests, data,
markdown, and image fixtures. It runs the suite there, removes the workspace,
and forwards the suite's exit status without changing your checkout:
git clone --depth 1 https://github.com/chobbledotcom/chobble-template.git /tmp/chobble-template-upstream
bun scripts/stage-hermetic-tests.js --template /tmp/chobble-template-upstream -- test/integration
This also points the fixture factory at the pristine checkout via the
CHOBBLE_TEMPLATE_FIXTURES_DIR env var, so fixture tests build isolated sites
from template defaults rather than your overrides. bun run test:hermetic -- --template <path> -- <args> runs the same thing via the package.json script.
Deployment
- GitHub Actions workflow for Neocities and Bunny.net
- Forgejo Actions support
- PagesCMS integration for no-code editing
- External ecommerce backend for payment processing
Configuration
_data/config.json- Formspark, Botpoison, ecommerce checkout, map embed, nav options_data/site.json- name, URL, description, social links (14 platforms), opening hours_data/meta.json- language, organisation details for schema.org_data/languages.json- languages the site publishes, and which is the base_data/translations.json- pages that say the same thing in each language_data/strings.json- customisable labels and permalink directories
Want a website based on this template? Clone this repo, or hit me up at Chobble.com.