This repository contains the source code for The Refract Foundation's public website.
The Refract Foundation is a youth-led, West Midlands–based initiative working to improve digital literacy and access to opportunity in schools. Our programmes — Census, RAISE, Revise and Futures — along with events like Campfire, help young people build the confidence, skills and opportunities to thrive in a digital world.
The site is a static site built with Jekyll, styled with Bootstrap, and deployed on Vercel.
- 📄 Static pages for our mission, programmes, news and policies
- 🗞️ Markdown-based news posts with author, date and cover image support
- 📊 Data-driven content (programmes, partners, team, values) via
_data/*.yml - 🔍 SEO support through
jekyll-seo-tagand auto-generated sitemaps
| Component | Technology |
|---|---|
| Static site | Jekyll 4.4.1 (Ruby) |
| CSS framework | Bootstrap 5 (vendored in scripts/bootstrap-dist/) |
| Styling | Custom CSS in assets/style.css |
| Build helpers | Node.js ≥ 20 + sharp |
| Deployment | Vercel |
- Ruby (2.7+) with Bundler
- Node.js ≥ 20 (for the image optimisation script)
# Clone the repository
git clone <repository-url>cd site
# Install Ruby dependencies
bundle install
# Install Node dependencies
npm installbundle exec jekyll serve --livereloadThe site will be available at http://localhost:4000, with live reload enabled.
bundle exec jekyll buildThe generated site is written to _site/.
Source images (.jpg, .jpeg, .png) live in assets/images/. The build pipeline serves WebP versions automatically:
npm run generate-webpconverts every image inassets/images/to.webp(quality 75) using sharp. Conversions are skipped when the.webpis already newer than the source. You can target a specific directory:npm run generate-webp assets/images/campfire._plugins/webp_hook.rbpost-processes the rendered HTML: it wraps<img>tags in<picture>elements with a WebP<source>when one exists, and rewritesurl()references in inline styles (used for hero slides and event-card backgrounds).
⚠️ Runnpm run generate-webpafter adding new images so the optimised versions exist before building.
.
├── _config.yml # Jekyll configuration
├── _data/ # Site data (nav, programmes, team, partners, values…)
├── _includes/ # Reusable partials (header, footer, donate, news…)
├── _layouts/ # Page templates (index, page, post, programme)
├── _plugins/ # Custom Jekyll plugins (WebP HTML hook)
├── assets/
│ ├── images/ # All site imagery (JPG/PNG sources + generated WebP)
│ └── style.css # Global styles
├── news/ # News posts (Markdown + front matter)
├── our-work/ # Programme & campaign pages
├── scripts/
│ ├── generate-webp.js # Node WebP conversion script
│ └── bootstrap-dist/ # Vendored Bootstrap CSS/JS
├── Gemfile # Ruby dependencies
├── package.json # Node dependencies & scripts
└── vercel.json # Vercel build & redirect configuration
Create a Markdown file in news/ with the following front matter:
---
title: My Post Titlelayout: postauthor: Your Namedate: 2026-01-01cover: /assets/images/example.jpgpermalink: /news/my-post-title
---
Post content in Markdown…Programme cards on the homepage are driven by _data/programmes.yml. Each entry includes a name, logo, description, background image, colour and URL.
Navigation, partners, team members, values and contact details are all managed as YAML in _data/ — no HTML changes required.
Deployment is handled by Vercel using the configuration in vercel.json:
{
"buildCommand": "npm ci && node scripts/generate-webp.js && bundle exec jekyll build",
"cleanUrls": true,
"redirects": []
}The build pipeline installs dependencies, generates WebP assets, then builds the site. Clean URLs strip .html extensions, and a couple of permanent redirects keep old URLs working:
/events/:path*→/our-work/:path*/our-work/dlc→/our-work/census
This project is licensed under the GNU General Public License v3.0.