Skip to content

Latest commit

 

History

18 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

KOKOLIKOOO — Fresh Chicken Delivered to Kigali

KOKOLIKOOO is Kacy Farms' poultry brand, serving hotels, supermarkets, and restaurants across Kigali, Rwanda. We deliver fresh, chilled chicken — 150 tons per year, always on time.

Brand

  • Brand Name: KOKOLIKOOO
  • Company: Kacy Farms (Kacy Ltd)
  • Website: https://kacy.rw

Pages

Page URL Description
Home / Products, quality, certifications, FAQ
About /about/ Company story, business units, values
Contact /contact/ Contact form, phone, location map
Blog /blog/ Poultry sourcing insights for Kigali kitchens
Privacy Policy /privacy-policy/ Data handling policy
404 /404.html Custom error page

Chicken meat SEO pages

Nine commercial and informational pages for chicken meat. They are not in the navbar by design — they are reached from the sitemap, from contextual links on the homepage and blog, and from the cross-links on each other. Adding them to the navbar would push the core four nav items out of a sensible hierarchy.

Page URL Primary intent
Chicken meat hub /chicken-meat/ Product range, the commercial entry point
Chicken cuts /chicken-cuts/ "chicken cuts explained", weights and yields
Processing /chicken-meat-processing/ On-site processing, cut-to-spec
Delivery /chicken-meat-delivery/ Delivery coverage, standing orders
Wholesale /wholesale-chicken-supply/ B2B specs, volumes, scheduling
Buyer's guide /chicken-meat-guide/ Weights, yields, spotting fresh meat
How to cook /how-to-cook-chicken/ Prep, 74 °C rule, times per cut
Nutrition /chicken-nutrition/ Protein/calories/fat per cut
Safety /fresh-chicken-safety/ Storage, shelf life, thawing

Each page ships a @graph of Organization → WebSite → LocalBusiness → WebPage → page-specific node (ItemList, Service, or HowTo) → BreadcrumbList → FAQPage, with visible FAQ answers that match the schema. No prices are published anywhere, so there is nothing to become stale.

Contact form delivery

The contact form posts to /api/contact, a Cloudflare Pages Function that validates the submission and relays it through the Resend HTTP API to info@kacy.rw. There is no third-party form service in the loop.

  • Function: functions/api/contact.js (Pages Functions routing, so functions/api/contact.js → POST /api/contact).
  • Client: js/contact-form.js, progressive enhancement — the form posts normally without JavaScript and upgrades to fetch with it.
  • Spam controls: honeypot field, minimum fill time, payload size cap, and a best-effort per-isolate throttle. The throttle is in-memory, so it is a speed bump rather than a hard limit. Enforce real limits at the edge (WAF rule or Turnstile) if the endpoint gets abused.
  • Note: message bodies are deliberately truncated before email. Very long submissions are cut down rather than sent in full.

Configuration

Set the API key as a Pages secret — never in wrangler.toml:

npx wrangler pages secret put RESEND_API_KEY --project-name kacy

wrangler.toml holds the non-secret overrides:

Variable Default Purpose
MAIL_FROM KOKOLIKOOO Website <website@kacy.rw> Resend verified sender. Must be a domain verified in Resend, otherwise the API rejects it.
MAIL_TO info@kacy.rw Where enquiries land.
ALLOWED_ORIGINS https://kacy.rw,https://www.kacy.rw Comma-separated CORS allowlist. Add preview domains when testing.

Locally, python -m http.server will not run the function. Use Wrangler so /api/contact resolves:

npx wrangler pages dev .

Project Structure

KACY/
├── index.html                     # Home page
├── 404.html                       # Error page
├── about/
│   └── index.html                 # About page
├── blog/
│   ├── index.html                 # Blog index
│   ├── choose-chicken-supplier-kigali/index.html
│   ├── whole-chicken-vs-cuts/index.html
│   └── cold-chain-fresh-chicken/index.html
├── chicken-meat/index.html        # Product hub
├── chicken-cuts/index.html        # Cut reference
├── chicken-meat-processing/       # Processing capabilities
├── chicken-meat-delivery/         # Delivery coverage
├── wholesale-chicken-supply/      # B2B supply
├── chicken-meat-guide/            # Buyer's guide
├── how-to-cook-chicken/           # Cooking guide
├── chicken-nutrition/             # Nutrition facts
├── fresh-chicken-safety/          # Food safety guide
├── contact/
│   └── index.html                 # Contact page
├── privacy-policy/
│   └── index.html                 # Privacy policy
├── components/
│   ├── navbar.html                # Navigation (inlined into every page)
│   └── footer.html                # Footer (inlined into every page)
├── functions/
│   └── api/
│       └── contact.js             # Pages Function: POST /api/contact -> Resend
├── css/
│   ├── style.css                  # Custom styles (self-hosted font, utilities)
│   ├── tailwind.css               # Built Tailwind CSS (generated)
│   └── input.css                  # Tailwind entry point
├── js/
│   ├── main.js                    # Mobile menu + hydration (no content fetch)
│   └── contact-form.js            # Progressive form submission
├── assets/
│   ├── fonts/google-sans-latin.woff2   # Self-hosted Google Sans (latin subset)
│   └── images/                    # WebP/AVIF assets only
├── tailwind.config.js             # Tailwind configuration
├── wrangler.toml                  # Cloudflare Pages config + mail vars
├── .assetsignore                  # Keeps repo-only files out of the deploy
├── package.json                   # Build scripts
├── sitemap.xml                    # XML sitemap with image tags
└── robots.txt                     # Search engine config

Recent SEO work

This is a static, SEO-first site. Highlights of the latest audit-driven refresh:

  • Crawlable navigation: the navbar and footer are inlined into every HTML page (no client-side fetch()), so internal links are present in the HTML source that crawlers see and there is no layout shift while they load.
  • Valid structured data: every page ships a valid @graph of Organization → LocalBusiness → WebSite → BreadcrumbList (Article/BlogPosting on blog posts, FAQPage on the home page). Product offers are expressed as an OfferCatalog so no fabricated prices are ever published.
  • Image SEO: all images are self-hosted, WebP (logos/photos) or AVIF, carry descriptive filenames and alt text, and have width/height to remove layout shift. A dedicated 1200×630 og-image.jpg is used for social previews.
  • Performance: Google Fonts (Google Sans) are self-hosted from /assets/fonts/ and preloaded; the Font Awesome kit is loaded with defer.
  • Local SEO: NAP (name/address/phone) is consistent across the footer, JSON-LD, maps embed, and hCard; the LocalBusiness geo coordinates match the Google Maps pin.
  • Content: a Blog section targets long-tail Kigali/B2B queries such as "chicken supplier Kigali", "whole chicken vs cuts", and "chicken cold chain", and the nine chicken meat pages under Chicken meat SEO pages above target "chicken cuts", "chicken meat delivery Kigali", "how to cook chicken" and "chicken nutrition per cut".
  • Sitemap-only discoverability: the nine pages are deliberately kept out of the navbar. They are discoverable via sitemap.xml, contextual links on the homepage and blog, and the cross-link grid at the foot of each page.
  • No fabricated claims: no prices are published, and certification language is deliberately held to what the homepage states — a documented HACCP-based plan and RSB registration, with formal HACCP certification still in progress. Keep the two in step if either changes.

Development

Prerequisites

  • Node.js 18+

Getting Started

# Install dependencies
npm install

# Build CSS
npm run build:css

# Watch for changes (automatic rebuild)
npm run watch:css

Open index.html in your browser, or serve locally:

# Using Python
python -m http.server 8000

# Using Node.js
npx serve

Building for Production

npm run build

This generates a minified css/tailwind.css from the HTML content sources. Always rebuild before deploying.

Deploying

Cloudflare Pages serves both the static files and the functions/ directory, and wrangler.toml points pages_build_output_dir at the repository root.

npm run build                       # rebuild Tailwind first
npx wrangler pages deploy . --project-name kacy

.assetsignore keeps repo-only paths out of the upload — most importantly .kilo/, which holds a stale worktree copy of the site that would otherwise be published as a second, outdated version still containing the removed Formspree form.

pages_build_output_dir = "." means the whole repository is the site root. If you add a directory that should not be public, add it to .assetsignore.

SEO

  • Structured Data: Organization, WebSite, LocalBusiness, WebPage, OfferCatalog, FAQPage, BreadcrumbList, plus ItemList / Service / HowTo on the chicken meat pages and Article/BlogPosting on blog posts — all valid @graph.
  • Open Graph + Twitter Cards: og-image.jpg (1200×630) preview tags with dimensions and alt text on every page.
  • Sitemap: XML with image tags, submitted via robots.txt.
  • Local SEO: Consistent NAP across footer, JSON-LD, and hCard; geo coords match the Google Maps pin.
  • Canonical URLs: Trailing-slash canonicals on every page; no hreflang (single-language site).
  • Titles and descriptions: kept at or under 60 and 158 characters respectively, matching the existing pages, so nothing is truncated in results.
  • Content: /blog/ targets long-tail Kigali/B2B queries, and the nine chicken meat pages target cut, delivery, cooking, nutrition and safety searches.
  • FAQ integrity: every FAQPage answer matches the visible accordion text on the same page. If you edit one, edit both.

Copy Style

All website copy is written in plain, conversational language. No jargon, no corporate speak. The tone is direct and human — like talking to a real person who can help.

Technologies

  • HTML5: Semantic markup, inlined navbar/footer for crawlability
  • Tailwind CSS v3: Pre-built via CLI (not CDN)
  • Vanilla JavaScript: ES6 modules (mobile menu and contact form; no content fetching)
  • Cloudflare Pages Functions: POST /api/contact, with Resend for delivery
  • Font Awesome: Icons via deferred kit script (CDN)
  • Fonts: Google Sans (self-hosted latin-subset WOFF2 in /assets/fonts/)
  • Analytics: Google Analytics 4 (gtag, async)

Updating Content

The navbar and footer are inlined into every HTML page rather than loaded via JavaScript. When you update components/navbar.html or components/footer.html, apply the same change in every page's nav/footer block. There is no JS component loader, so static edits are instantly live.

When editing a chicken meat page, remember three places must agree: the visible copy, the JSON-LD @graph, and the cross-link grid at the foot of the page. A new page also needs a sitemap.xml entry.

  • Logo: Replace assets/images/kokolikooo-logo.webp. It is referenced in the navbar, footer, and JSON-LD logo/og:image of every page.
  • Hero image: Replace assets/images/kacy-farms-hero.webp on the home page.
  • Delivery vehicle / facility photos: swap delivery-truck-*.webp, processing-facility.webp, kacy-motel.webp, real-estate.webp.
  • Social links: update the social <a> hrefs and the sameAs JSON-LD arrays (one source of truth: components/footer.html + the Organization block on each page).
  • Fonts: the Google Sans WOFF2 is self-hosted in assets/fonts/. Edit the @font-face rule in css/style.css, not a <link> to Google Fonts.
  • Contact Info: NAP lives in components/footer.html, contact/index.html, and the LocalBusiness JSON-LD on every page — keep them in sync.
  • Certifications: the homepage shows RSB and HACCP as in progress. Do not describe either as held until that changes, on any page.
  • After any HTML or Tailwind class change: run npm run build:css (Tailwind is purged against the HTML content). Static copy edits (text, inline styles) need no build step.

Contact

  • Phone: +250 788 309 077 | +250 788 867 296
  • Email: info@kacy.rw
  • Address: Cyanamo, Kabuga II, Rusororo, Gasabo District, Kigali, Rwanda

License

Copyright © 2026 KOKOLIKOOO by Kacy Farms. All rights reserved.

About

Kacy Website

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages