Improve SEO content
This commit is contained in:
BIN
assets/images/logo.png
Normal file
BIN
assets/images/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.1 MiB |
BIN
assets/images/og-logo.png
Normal file
BIN
assets/images/og-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 5.1 KiB |
BIN
assets/images/og-logo.xcf
Normal file
BIN
assets/images/og-logo.xcf
Normal file
Binary file not shown.
114
docs/SEO-IMPROVEMENTS.md
Normal file
114
docs/SEO-IMPROVEMENTS.md
Normal file
@@ -0,0 +1,114 @@
|
||||
# SEO Improvements Documentation
|
||||
|
||||
## Overview
|
||||
This project has been enhanced with comprehensive SEO capabilities using a modular partial system in Hugo.
|
||||
|
||||
## File Structure
|
||||
```
|
||||
layouts/partials/seo/
|
||||
├── seo-config.html # Main SEO configuration loader
|
||||
├── seo-meta.html # Core SEO meta tags
|
||||
├── opengraph.html # Open Graph tags for social media
|
||||
├── twitter-cards.html # Twitter Card tags
|
||||
├── structured-data.html # JSON-LD schema markup
|
||||
└── favicons.html # Favicon variations and PWA support
|
||||
```
|
||||
|
||||
## Features Added
|
||||
|
||||
### 1. Core SEO Meta Tags
|
||||
- Dynamic meta description
|
||||
- Keywords (with fallback)
|
||||
- Author information
|
||||
- Canonical URLs
|
||||
- Robots meta tags
|
||||
- Dublin Core metadata
|
||||
- Geo tags (if configured)
|
||||
|
||||
### 2. Open Graph Tags
|
||||
- og:title, og:description, og:image
|
||||
- og:type (article/website)
|
||||
- og:site_name
|
||||
- og:url
|
||||
- Article-specific tags for blog posts
|
||||
|
||||
### 3. Twitter Cards
|
||||
- twitter:card (summary_large_image)
|
||||
- twitter:title, twitter:description
|
||||
- twitter:image
|
||||
- Site and creator handles
|
||||
|
||||
### 4. Structured Data (JSON-LD)
|
||||
- WebSite schema
|
||||
- Article schema for blog posts
|
||||
- BreadcrumbList schema
|
||||
- Organization schema
|
||||
|
||||
### 5. Favicon & PWA Support
|
||||
- Multiple favicon sizes
|
||||
- Apple Touch Icons
|
||||
- Android icons
|
||||
- PWA manifest.json
|
||||
- Theme colors
|
||||
|
||||
## Configuration
|
||||
|
||||
### Hugo Configuration (hugo.toml)
|
||||
```toml
|
||||
[params.seo]
|
||||
description = "Your site description"
|
||||
keywords = ["keyword1", "keyword2"]
|
||||
author = "Your Name"
|
||||
theme_color = "#007bff"
|
||||
default_image = "/images/og-default.jpg"
|
||||
logo = "/images/logo.png"
|
||||
|
||||
[params.seo.twitter]
|
||||
site = "@yourhandle"
|
||||
creator = "@yourhandle"
|
||||
```
|
||||
|
||||
### Content Frontmatter
|
||||
Add to your content's frontmatter:
|
||||
```yaml
|
||||
---
|
||||
title: "Your Post Title"
|
||||
description: "Detailed description for SEO"
|
||||
keywords: ["seo", "hugo", "optimization"]
|
||||
author: "Author Name"
|
||||
image: "/images/post-image.jpg"
|
||||
robots: "index, follow"
|
||||
---
|
||||
```
|
||||
|
||||
## Testing & Validation
|
||||
|
||||
### Recommended Tools
|
||||
- Google Rich Results Test: https://search.google.com/test/rich-results
|
||||
- Facebook Sharing Debugger: https://developers.facebook.com/tools/debug/
|
||||
- Twitter Card Validator: https://cards-dev.twitter.com/validator
|
||||
- Schema.org Validator: https://validator.schema.org/
|
||||
|
||||
### Validation Checklist
|
||||
- [ ] Meta tags present in page source
|
||||
- [ ] Open Graph tags validate
|
||||
- [ ] Twitter Cards validate
|
||||
- [ ] JSON-LD schema validates
|
||||
- [ ] Favicons load correctly
|
||||
- [ ] Canonical URLs are correct
|
||||
|
||||
## Next Steps
|
||||
1. Generate favicon files for all sizes (use a favicon generator)
|
||||
2. Create og-default.jpg and twitter-default.jpg images
|
||||
3. Set up Google Search Console and add verification code
|
||||
4. Set up Bing Webmaster Tools
|
||||
5. Test with social media sharing
|
||||
|
||||
## Fallback Values
|
||||
The system includes intelligent fallback values:
|
||||
- Description: Page → Site → Title
|
||||
- Keywords: Page → Site → Empty string
|
||||
- Image: Page → Site → Default
|
||||
- Author: Page → Site → Site Title
|
||||
|
||||
All SEO improvements have been successfully implemented!
|
||||
43
hugo.toml
43
hugo.toml
@@ -13,6 +13,32 @@ ignoreLogs = ["warning-goldmark-raw-html"]
|
||||
[markup.goldmark.renderer]
|
||||
unsafe = true
|
||||
|
||||
# SEO Configuration
|
||||
[params.seo]
|
||||
description = "Mistergeek - Tutoriels et guides en informatique"
|
||||
keywords = ["développement web", "technologies", "innovation", "solutions digitales", "mistergeek"]
|
||||
author = "Mistergeek"
|
||||
theme_color = "#007bff"
|
||||
default_image = "/assets/images/og-logo.png"
|
||||
logo = "/assets/images/logo.png"
|
||||
|
||||
# Social Media
|
||||
[params.seo.twitter]
|
||||
site = "@mistergeekfrance"
|
||||
creator = "@mistergeekfrance"
|
||||
|
||||
# Search Engine Verification
|
||||
# google_verification = "your-google-verification-code"
|
||||
# bing_verification = "your-bing-verification-code"
|
||||
# yandex_verification = "your-yandex-verification-code"
|
||||
|
||||
# Geo Location (if applicable)
|
||||
# [params.seo.geo]
|
||||
# region = "FR-IDF"
|
||||
# placename = "Paris"
|
||||
# latitude = "48.8566"
|
||||
# longitude = "2.3522"
|
||||
|
||||
# WordPress API Configuration
|
||||
[params.wordpress]
|
||||
apiUrl = "https://www.mistergeek.net/wp-json/wp/v2"
|
||||
@@ -31,3 +57,20 @@ ignoreLogs = ["warning-goldmark-raw-html"]
|
||||
[[build.cachebusters]]
|
||||
source = "assets/.*\\.(css|sass|scss)$"
|
||||
target = "css"
|
||||
|
||||
# Output formats for search index
|
||||
[outputs]
|
||||
home = ["HTML", "RSS", "JSON"]
|
||||
|
||||
[outputFormats]
|
||||
[outputFormats.JSON]
|
||||
mediaType = "application/json"
|
||||
baseName = "search-index"
|
||||
isPlainText = true
|
||||
notAlternative = true
|
||||
|
||||
# Search configuration
|
||||
[params.search]
|
||||
enabled = true
|
||||
minQueryLength = 2
|
||||
maxResults = 10
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<html lang="{{ .Site.Language.Lang | default "en" }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<meta name="description" content="{{ if .Description }}{{ .Description }}{{ else }}{{ .Site.Title }}{{ end }}">
|
||||
<meta name="keywords" content="">
|
||||
|
||||
<!-- SEO & Social Meta Tags -->
|
||||
<title>{{ if .IsHome }}{{ .Site.Title }}{{ else }}{{ .Title }} - {{ .Site.Title }}{{ end }}</title>
|
||||
<!-- Favicon -->
|
||||
<link href="/assets/images/favicon.png" rel="shortcut icon">
|
||||
{{ partial "seo/seo-config.html" . }}
|
||||
|
||||
<!-- CSS -->
|
||||
<link href="/assets/plugins/bootstrap/bootstrap.min.css" rel="stylesheet">
|
||||
<link href="/assets/plugins/owl-carousel/owl.carousel.min.css" rel="stylesheet">
|
||||
@@ -68,5 +68,6 @@
|
||||
<script src="/assets/plugins/jquery.min.js"></script>
|
||||
<script src="/assets/plugins/plugins.js"></script>
|
||||
<script src="/assets/js/functions.js"></script>
|
||||
{{ partial "scripts.html" . }}
|
||||
</body>
|
||||
</html>
|
||||
3
layouts/partials/scripts.html
Normal file
3
layouts/partials/scripts.html
Normal file
@@ -0,0 +1,3 @@
|
||||
<!-- Search Scripts -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/lunr@2.3.9/lunr.min.js"></script>
|
||||
<script src="/assets/js/search.js"></script>
|
||||
32
layouts/partials/seo/favicons.html
Normal file
32
layouts/partials/seo/favicons.html
Normal file
@@ -0,0 +1,32 @@
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="/assets/images/favicon.ico">
|
||||
<link rel="shortcut icon" type="image/x-icon" href="/assets/images/favicon.ico">
|
||||
|
||||
<!-- Apple Touch Icons -->
|
||||
<link rel="apple-touch-icon" sizes="57x57" href="/assets/images/apple-touch-icon-57x57.png">
|
||||
<link rel="apple-touch-icon" sizes="60x60" href="/assets/images/apple-touch-icon-60x60.png">
|
||||
<link rel="apple-touch-icon" sizes="72x72" href="/assets/images/apple-touch-icon-72x72.png">
|
||||
<link rel="apple-touch-icon" sizes="76x76" href="/assets/images/apple-touch-icon-76x76.png">
|
||||
<link rel="apple-touch-icon" sizes="114x114" href="/assets/images/apple-touch-icon-114x114.png">
|
||||
<link rel="apple-touch-icon" sizes="120x120" href="/assets/images/apple-touch-icon-120x120.png">
|
||||
<link rel="apple-touch-icon" sizes="144x144" href="/assets/images/apple-touch-icon-144x144.png">
|
||||
<link rel="apple-touch-icon" sizes="152x152" href="/assets/images/apple-touch-icon-152x152.png">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/assets/images/apple-touch-icon-180x180.png">
|
||||
|
||||
<!-- Android Icons -->
|
||||
<link rel="icon" type="image/png" sizes="192x192" href="/assets/images/android-icon-192x192.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/assets/images/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="96x96" href="/assets/images/favicon-96x96.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/assets/images/favicon-16x16.png">
|
||||
|
||||
<!-- Microsoft Tiles -->
|
||||
<meta name="msapplication-TileColor" content="{{ .Site.Params.seo.theme_color | default "#007bff" }}">
|
||||
<meta name="msapplication-TileImage" content="/assets/images/ms-icon-144x144.png">
|
||||
<meta name="msapplication-config" content="/assets/images/browserconfig.xml">
|
||||
|
||||
<!-- PWA Manifest -->
|
||||
<link rel="manifest" href="/manifest.json">
|
||||
|
||||
<!-- Theme Color -->
|
||||
<meta name="theme-color" content="{{ .Site.Params.seo.theme_color | default "#007bff" }}">
|
||||
<meta name="msapplication-TileColor" content="{{ .Site.Params.seo.theme_color | default "#007bff" }}">
|
||||
33
layouts/partials/seo/opengraph.html
Normal file
33
layouts/partials/seo/opengraph.html
Normal file
@@ -0,0 +1,33 @@
|
||||
{{- $title := .Title | default .Site.Title -}}
|
||||
{{- $description := .Description | default .Summary | default .Site.Params.description | default .Site.Title -}}
|
||||
{{- $image := .Params.image | default .Site.Params.seo.default_image | default "/assets/images/og-default.jpg" -}}
|
||||
{{- $image = $image | absURL -}}
|
||||
{{- $url := .Permalink | default .RelPermalink | absURL -}}
|
||||
{{- $siteName := .Site.Title -}}
|
||||
{{- $locale := .Site.Language.Lang | default "en_US" -}}
|
||||
|
||||
<!-- Open Graph / Facebook -->
|
||||
<meta property="og:type" content="{{ if .IsPage }}article{{ else }}website{{ end }}">
|
||||
<meta property="og:site_name" content="{{ $siteName }}">
|
||||
<meta property="og:title" content="{{ $title }}">
|
||||
<meta property="og:description" content="{{ $description }}">
|
||||
<meta property="og:url" content="{{ $url }}">
|
||||
<meta property="og:locale" content="{{ $locale }}">
|
||||
<meta property="og:image" content="{{ $image }}">
|
||||
<meta property="og:image:alt" content="{{ $title }}">
|
||||
<meta property="og:image:width" content="1200">
|
||||
<meta property="og:image:height" content="630">
|
||||
|
||||
<!-- Article specific -->
|
||||
{{ if .IsPage }}
|
||||
<meta property="article:section" content="{{ .Section | default "general" }}">
|
||||
<meta property="article:author" content="{{ .Params.author | default .Site.Params.author | default .Site.Title }}">
|
||||
{{ range .Params.tags | default .Site.Params.tags }}
|
||||
<meta property="article:tag" content="{{ . }}">
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
|
||||
<!-- Additional locales for multilingual sites -->
|
||||
{{ range .Translations }}
|
||||
<meta property="og:locale:alternate" content="{{ .Language.Lang | default "en_US" }}">
|
||||
{{ end }}
|
||||
42
layouts/partials/seo/seo-config.html
Normal file
42
layouts/partials/seo/seo-config.html
Normal file
@@ -0,0 +1,42 @@
|
||||
{{- /* SEO Configuration Partial */ -}}
|
||||
{{- /* This partial includes all SEO-related partials */ -}}
|
||||
|
||||
<!-- Core SEO Meta Tags -->
|
||||
{{ partial "seo/seo-meta.html" . }}
|
||||
|
||||
<!-- Open Graph Tags -->
|
||||
{{ partial "seo/opengraph.html" . }}
|
||||
|
||||
<!-- Twitter Cards -->
|
||||
{{ partial "seo/twitter-cards.html" . }}
|
||||
|
||||
<!-- Structured Data (JSON-LD) -->
|
||||
{{ partial "seo/structured-data.html" . }}
|
||||
|
||||
<!-- Favicons and PWA Support -->
|
||||
{{ partial "seo/favicons.html" . }}
|
||||
|
||||
<!-- Additional SEO Tags -->
|
||||
{{- if .Site.Params.seo.google_verification }}
|
||||
<meta name="google-site-verification" content="{{ .Site.Params.seo.google_verification }}">
|
||||
{{ end }}
|
||||
|
||||
{{- if .Site.Params.seo.bing_verification }}
|
||||
<meta name="msvalidate.01" content="{{ .Site.Params.seo.bing_verification }}">
|
||||
{{ end }}
|
||||
|
||||
{{- if .Site.Params.seo.yandex_verification }}
|
||||
<meta name="yandex-verification" content="{{ .Site.Params.seo.yandex_verification }}">
|
||||
{{ end }}
|
||||
|
||||
{{- if .Site.Params.seo.alexa_verification }}
|
||||
<meta name="alexaVerifyID" content="{{ .Site.Params.seo.alexa_verification }}">
|
||||
{{ end }}
|
||||
|
||||
<!-- hreflang for multilingual sites -->
|
||||
{{ range .Translations }}
|
||||
<link rel="alternate" hreflang="{{ .Language.Lang }}" href="{{ .Permalink }}">
|
||||
{{ end }}
|
||||
{{ if .IsTranslated }}
|
||||
<link rel="alternate" hreflang="x-default" href="{{ .Permalink }}">
|
||||
{{ end }}
|
||||
40
layouts/partials/seo/seo-meta.html
Normal file
40
layouts/partials/seo/seo-meta.html
Normal file
@@ -0,0 +1,40 @@
|
||||
{{- $description := .Description | default .Summary | default .Site.Params.description | default .Site.Title -}}
|
||||
{{- $keywords := delimit (.Keywords | default .Site.Params.keywords | default (slice)) ", " -}}
|
||||
{{- $author := .Params.author | default .Site.Params.author | default .Site.Title -}}
|
||||
{{- $robots := .Params.robots | default "index, follow" -}}
|
||||
{{- $canonical := .Permalink | default .RelPermalink -}}
|
||||
|
||||
<!-- Primary Meta Tags -->
|
||||
<meta name="description" content="{{ $description }}">
|
||||
<meta name="keywords" content="{{ $keywords }}">
|
||||
<meta name="author" content="{{ $author }}">
|
||||
<meta name="robots" content="{{ $robots }}">
|
||||
<meta name="generator" content="Hugo {{ hugo.Version }}">
|
||||
|
||||
<!-- Canonical URL -->
|
||||
<link rel="canonical" href="{{ $canonical }}">
|
||||
|
||||
<!-- Theme Color -->
|
||||
<meta name="theme-color" content="{{ .Site.Params.seo.theme_color | default "#007bff" }}">
|
||||
<meta name="msapplication-TileColor" content="{{ .Site.Params.seo.theme_color | default "#007bff" }}">
|
||||
|
||||
<!-- Additional SEO -->
|
||||
<meta name="rating" content="general">
|
||||
<meta name="language" content="{{ .Site.Language.Lang | default "en" }}">
|
||||
<meta name="revisit-after" content="7 days">
|
||||
<meta name="distribution" content="global">
|
||||
<meta name="web_author" content="{{ .Site.Params.author | default .Site.Title }}">
|
||||
|
||||
<!-- Geo Tags (if location is specified) -->
|
||||
{{ with .Site.Params.seo.geo }}
|
||||
<meta name="geo.region" content="{{ .region }}">
|
||||
<meta name="geo.placename" content="{{ .placename }}">
|
||||
<meta name="geo.position" content="{{ .latitude }};{{ .longitude }}">
|
||||
<meta name="ICBM" content="{{ .latitude }}, {{ .longitude }}">
|
||||
{{ end }}
|
||||
|
||||
<!-- Dublin Core -->
|
||||
<meta name="DC.Title" content="{{ .Title | default .Site.Title }}">
|
||||
<meta name="DC.Creator" content="{{ $author }}">
|
||||
<meta name="DC.Description" content="{{ $description }}">
|
||||
<meta name="DC.Language" content="{{ .Site.Language.Lang | default "en" }}">
|
||||
85
layouts/partials/seo/structured-data.html
Normal file
85
layouts/partials/seo/structured-data.html
Normal file
@@ -0,0 +1,85 @@
|
||||
{{- $title := .Title | default .Site.Title -}}
|
||||
{{- $description := .Description | default .Summary | default .Site.Params.description | default .Site.Title -}}
|
||||
{{- $image := .Params.image | default .Site.Params.seo.default_image | default "/assets/images/logo.png" -}}
|
||||
{{- $image = $image | absURL -}}
|
||||
{{- $url := .Permalink | default .RelPermalink | absURL -}}
|
||||
{{- $siteName := .Site.Title -}}
|
||||
{{- $logo := .Site.Params.seo.logo | default "/assets/images/logo.png" | absURL -}}
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
"name": "{{ $siteName }}",
|
||||
"description": "{{ $description }}",
|
||||
"url": "{{ .Site.BaseURL }}",
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": "{{ $logo }}"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{{ if .IsPage }}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Article",
|
||||
"headline": "{{ $title }}",
|
||||
"description": "{{ $description }}",
|
||||
"image": "{{ $image }}",
|
||||
"url": "{{ $url }}",
|
||||
"author": {
|
||||
"@type": "Person",
|
||||
"name": "{{ .Params.author | default .Site.Params.author | default .Site.Title }}"
|
||||
},
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "{{ $siteName }}",
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": "{{ $logo }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{{ end }}
|
||||
|
||||
<!-- Breadcrumb Schema -->
|
||||
{{ if and .IsPage .Section }}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 1,
|
||||
"name": "Accueil",
|
||||
"item": "{{ .Site.BaseURL }}"
|
||||
}
|
||||
{{ if .Section }}
|
||||
,{
|
||||
"@type": "ListItem",
|
||||
"position": 2,
|
||||
"name": "{{ .Section | humanize }}",
|
||||
"item": "{{ .Site.BaseURL }}{{ .Section }}/"
|
||||
}
|
||||
,{
|
||||
"@type": "ListItem",
|
||||
"position": 3,
|
||||
"name": "{{ $title }}",
|
||||
"item": "{{ $url }}"
|
||||
}
|
||||
{{ else }}
|
||||
,{
|
||||
"@type": "ListItem",
|
||||
"position": 2,
|
||||
"name": "{{ $title }}",
|
||||
"item": "{{ $url }}"
|
||||
}
|
||||
{{ end }}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{{ end }}
|
||||
27
layouts/partials/seo/twitter-cards.html
Normal file
27
layouts/partials/seo/twitter-cards.html
Normal file
@@ -0,0 +1,27 @@
|
||||
{{- $title := .Title | default .Site.Title -}}
|
||||
{{- $description := .Description | default .Summary | default .Site.Params.description | default .Site.Title -}}
|
||||
{{- $image := .Params.image | default .Site.Params.seo.default_image | default "/assets/images/twitter-default.jpg" -}}
|
||||
{{- $image = $image | absURL -}}
|
||||
{{- $siteName := .Site.Title -}}
|
||||
{{- $twitter := .Site.Params.seo.twitter -}}
|
||||
|
||||
<!-- Twitter Card -->
|
||||
<meta name="twitter:card" content="summary_large_image">
|
||||
<meta name="twitter:title" content="{{ $title }}">
|
||||
<meta name="twitter:description" content="{{ $description }}">
|
||||
<meta name="twitter:image" content="{{ $image }}">
|
||||
<meta name="twitter:image:alt" content="{{ $title }}">
|
||||
|
||||
<!-- Twitter Site -->
|
||||
{{ with $twitter.site }}
|
||||
<meta name="twitter:site" content="{{ . }}">
|
||||
{{ end }}
|
||||
|
||||
<!-- Twitter Creator -->
|
||||
{{ with $twitter.creator }}
|
||||
<meta name="twitter:creator" content="{{ . }}">
|
||||
{{ else }}
|
||||
{{ with .Params.author }}
|
||||
<meta name="twitter:creator" content="{{ . }}">
|
||||
{{ end }}
|
||||
{{ end }}
|
||||
Reference in New Issue
Block a user