Add comprehensive SEO optimization
All checks were successful
Deploy / Deploy to Production (push) Successful in 6s

Implement complete SEO setup for virtual product pages with:
- Meta tags (title, description, canonical, hreflang)
- Open Graph protocol for social sharing
- Twitter Card tags
- Schema.org structured data (JSON-LD) for products
- XML sitemap including virtual pages
- Dynamic meta tag updates via JavaScript

Changes:
- Create SEO snippet with all meta tags
- Add structured data snippet for products
- Generate sitemap.xml with products and hreflang
- Update meta tags dynamically when Shopify data loads
- Remove noindex/nofollow (was blocking all indexing)
- Add product-specific OG tags (price, availability)

All pages now properly indexed with correct multilingual setup.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
isUnknown 2026-01-16 17:02:27 +01:00
parent f69d990349
commit 9eb8d08bcc
8 changed files with 271 additions and 6 deletions

65
site/snippets/seo.php Normal file
View file

@ -0,0 +1,65 @@
<?php
/**
* SEO meta tags
*/
// Basic meta
$title = $page->customTitle()->or($page->title())->value();
$siteName = 'Index.ngo';
$fullTitle = $title . ' | ' . $siteName;
$description = $page->metaDescription()->or($page->description())->excerpt(160);
$url = $page->url();
$image = $page->image() ? $page->image()->url() : url('assets/og-image.jpg');
// Language
$lang = $kirby->language()->code();
?>
<!-- Basic Meta Tags -->
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $fullTitle ?></title>
<?php if ($description): ?>
<meta name="description" content="<?= $description ?>">
<?php endif ?>
<!-- Canonical & Alternate Languages -->
<link rel="canonical" href="<?= $url ?>">
<?php foreach($kirby->languages() as $language): ?>
<link rel="alternate" hreflang="<?= $language->code() ?>" href="<?= $page->url($language->code()) ?>">
<?php endforeach ?>
<link rel="alternate" hreflang="x-default" href="<?= $page->url('fr') ?>">
<!-- Open Graph -->
<meta property="og:type" content="<?= $page->template() == 'product' ? 'product' : 'website' ?>">
<meta property="og:site_name" content="<?= $siteName ?>">
<meta property="og:title" content="<?= $title ?>" id="og-title">
<meta property="og:description" content="<?= $description ?>" id="og-description">
<meta property="og:url" content="<?= $url ?>">
<meta property="og:image" content="<?= $image ?>" id="og-image">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<meta property="og:locale" content="<?= $lang == 'fr' ? 'fr_FR' : 'en_US' ?>">
<?php foreach($kirby->languages() as $language): ?>
<?php if ($language->code() != $lang): ?>
<meta property="og:locale:alternate" content="<?= $language->code() == 'fr' ? 'fr_FR' : 'en_US' ?>">
<?php endif ?>
<?php endforeach ?>
<?php if ($page->template() == 'product'): ?>
<!-- Product-specific OG tags (will be updated by JS) -->
<meta property="product:price:amount" content="0" id="og-price">
<meta property="product:price:currency" content="EUR">
<meta property="product:availability" content="in stock" id="og-availability">
<meta property="product:brand" content="Index.ngo">
<?php endif ?>
<!-- Twitter Card -->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="<?= $title ?>">
<?php if ($description): ?>
<meta name="twitter:description" content="<?= $description ?>">
<?php endif ?>
<meta name="twitter:image" content="<?= $image ?>">
<!-- Favicon -->
<link rel="icon" type="image/png" href="<?= url('assets/favicon.png') ?>">