Add tools/build_listings.py: copies the top 3 cards from each language's News
hub into the homepage "Latest news" block (marker-wrapped), so editing the News
page now updates the homepage. The News hub stays the hand-edited source of truth
(it may hold curated teaser cards without a detail page).
Also: fix the Gallery meta description (was a copy of the FAQ text) and add a
durable gallery override to seo_inject.py; refresh llms.txt / links-for-bots.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- consent.js: self-contained, non-blocking bottom banner in EN/MK/SI,
remembers the choice in localStorage, links to the per-language cookie
policy. Accept -> gtag consent 'update' granted; Decline stays denied.
- Head GA snippet restores a returning visitor's prior "granted" choice
before the first hit; loads /consent.js on every page.
- Re-openable via window.msosOpenConsent() for a "manage cookies" link.
Verified in-browser: shows for new visitors, Accept grants + remembers,
reload keeps consent without re-prompting, Slovene text + /si/ policy link.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- gtag.js injected on all 201 pages via tools/seo_inject.py + on 404.html
- Consent Mode v2 defaults all storage to 'denied' (EEA-safe: tag loads,
no tracking cookies until a consent banner grants analytics_storage)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add datePublished/dateModified to Article JSON-LD on the 11 dated
articles (curated once from EN, applied to all languages)
- Replace og-default.jpg with the official brand OG image (1200x630)
- Add docs/launch-seo-checklist.md (go-live steps: redirects, Search
Console, analytics, rich-result validation, monitoring)
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Add branded 1200x630 og-default.jpg; article pages use their hero as
og:image, others use the default
- Wire the existing (previously unlinked) favicon set into every page
- Add branded 404.html with root-absolute paths + noindex
- Emit Article + localized BreadcrumbList JSON-LD on all article pages
- Convert 74 heavy served photos to WebP (28MB -> 8.5MB, -70%), rewrite
references, add loading=lazy/decoding=async to below-fold images and
fetchpriority=high to heroes (protect LCP)
- Stop tracking images/original/ (458MB of unused source masters; kept on
disk, gitignored) and ignore .playwright-mcp/
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
SEO (all 201 pages, en/mk/si):
- Inject canonical, hreflang (en/mk/sl + x-default), Open Graph, Twitter
cards and Organization JSON-LD via idempotent SEO:START/END block
- Generate multilingual sitemap.xml (xhtml:link alternates) + robots.txt
- Curated meta descriptions for lead-less pages (home, become-a-member,
faq, news hub, my-route); every page now has a description
- Absolute URLs target final domain msosorg.com, not the temp host
- Add reusable tools/seo_inject.py (+ README)
Content fixes:
- Translate about-us and timeline-and-milestones into MK + SI, wire up
their pages, and repair the previously-dead "Who We Are" nav links
across all mk/si pages
- Remove duplicate en/projects/makedonska-studentska-vecer-vo-ljubljana
(unreferenced; already covered by macedonian-student-night-in-ljubljana)
Locale correctness:
- Normalise Slovene pages to <html lang="sl"> (correct ISO 639-1)
- Map sl->si in main.js so the language-switcher highlight and newsletter
i18n keep working on Slovene pages (data-lang="si" still maps to /si/)
MK/SI translations and descriptions are AI-drafted; flag for native review.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>