Add SEO improvements: canonical, hreflang, schema fixes, robots.txt
All checks were successful
ci/woodpecker/push/woodpecker Pipeline was successful

- Fix breadcrumb schema position bug (3 → 2) for Google Rich Results
- Override article/post schemas to use post image instead of site logo
- Fix og:type to emit "article" on post pages with published/modified times
- Add canonical link and hreflang alternate tags (incl. x-default) for bilingual site
- Add organizationName/organizationLogo params for valid Organization schema
- Add robots.txt with sitemap pointer
- Add preconnect hint for analytics host
This commit is contained in:
nemunaire 2026-03-12 11:07:10 +07:00
commit c8ff5c1d68
9 changed files with 164 additions and 20 deletions

View file

@ -28,6 +28,9 @@ params:
desc: "My school: Épita." desc: "My school: Épita."
link: "http://epita.fr/" link: "http://epita.fr/"
organizationName: "nemunaire's blog"
organizationLogo: "https://www.nemunai.re/img/mug.jpg"
author: author:
name: "nemunaire" name: "nemunaire"
email: "blog@nemunai.re" email: "blog@nemunai.re"

View file

@ -1,3 +1,11 @@
<link rel="canonical" href="{{ .Permalink }}" />
{{ if .IsTranslated }}
{{ range .AllTranslations }}
<link rel="alternate" hreflang="{{ .Lang }}" href="{{ .Permalink }}" />
{{ end }}
{{ range .AllTranslations }}{{ if eq .Lang "en" }}<link rel="alternate" hreflang="x-default" href="{{ .Permalink }}" />{{ end }}{{ end }}
{{ end }}
<link rel="preconnect" href="https://pythagore.p0m.fr" />
<script async defer data-website-id="714f2f10-3a65-4c5b-971f-7cea9eac1ecd" src="https://pythagore.p0m.fr/pythagore.js"></script> <script async defer data-website-id="714f2f10-3a65-4c5b-971f-7cea9eac1ecd" src="https://pythagore.p0m.fr/pythagore.js"></script>
<link rel="stylesheet" href="{{ "css/custom.css" | absURL }}" /> <link rel="stylesheet" href="{{ "css/custom.css" | absURL }}" />
<style> <style>

View file

@ -90,14 +90,15 @@
{{ if $thumbs }} {{ if $thumbs }}
<div class="container"> <div class="container">
{{range $i, $thumb := $thumbs}} <div class="thumbApps">
<a href="{{ $thumb.link | absURL }}" target="_blank"> {{range $i, $thumb := $thumbs}}
<div class="thumbApp" style="background-image:url('{{ $thumb.src | absURL }}')"> <a href="{{ $thumb.link | absURL }}" target="_blank">
{{ if $thumb.desc }}<p><span>{{ $thumb.desc }}</span></p>{{end}} <div class="thumbApp" style="background-image:url('{{ $thumb.src | absURL }}')">
</div> {{ if $thumb.desc }}<p><span>{{ $thumb.desc }}</span></p>{{end}}
</a> </div>
{{ end }} </a>
<span style="clear:both; display: block"></span> {{ end }}
</div>
<hr class="small"> <hr class="small">
</div> </div>
{{ end }} {{ end }}

View file

@ -0,0 +1,21 @@
{{- with .Title | default .Site.Title }}
<meta property="og:title" content="{{ . }}" />
{{- end }}
{{- with .Description | default .Params.subtitle | default .Summary }}
<meta property="og:description" content="{{ . }}">
{{- end }}
{{- with .Params.share_img | default .Params.image | default .Site.Params.logo }}
<meta property="og:image" content="{{ . | absURL }}" />
{{- end }}
{{- with .Site.Params.fb_app_id }}
<meta property="fb:app_id" content="{{ . }}" />
{{- end }}
<meta property="og:url" content="{{ .Permalink | absLangURL }}" />
{{- if .IsPage }}
<meta property="og:type" content="article" />
{{- with .PublishDate }}<meta property="article:published_time" content="{{ .Format "2006-01-02T15:04:05Z07:00" }}" />{{- end }}
{{- with .Lastmod }}<meta property="article:modified_time" content="{{ .Format "2006-01-02T15:04:05Z07:00" }}" />{{- end }}
{{- else }}
<meta property="og:type" content="website" />
{{- end }}
<meta property="og:site_name" content="{{ .Site.Title }}" />

View file

@ -0,0 +1,28 @@
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "Article",
"author": {
"name" : "{{ if .Params.author -}}{{ .Params.author }}{{- else if .Site.Params.author.name -}}{{ .Site.Params.author.name }}{{- end }}"
},
"headline": "{{ .Title }}",
"description" : "{{ if .Description }}{{ .Description | plainify }}{{ else }}{{if .IsPage}}{{ .Summary | plainify }}{{ end }}{{ end }}",
"inLanguage" : "{{ .Lang }}",
"wordCount": {{ .WordCount }},
"datePublished" : "{{ .PublishDate.Format "2006-01-02T15:04:05-07:00" }}",
"dateModified" : "{{ .Lastmod.Format "2006-01-02T15:04:05-07:00" }}",
"image" : "{{ .Params.share_img | default .Params.image | default .Site.Params.logo | absURL }}",
"keywords" : [ "{{ range $i, $e := .Params.tags }}{{ if $i }}, {{ end }}{{ $e }}{{ end }}" ],
"mainEntityOfPage" : "{{ .Permalink }}",
"publisher" : {
"@type": "Organization",
"name" : "{{ .Site.BaseURL }}",
"logo" : {
"@type" : "ImageObject",
"url" : "{{ .Site.Params.logo | absURL }}",
"height" : 60 ,
"width" : 60
}
}
}
</script>

View file

@ -0,0 +1,21 @@
<script type="application/ld+json">
{
"@context": "http://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [{
"@type": "ListItem",
"position": 1,
"item": {
"@id": "{{ .Site.BaseURL }}",
"name": "home"
}
},{
"@type": "ListItem",
"position": 2,
"item": {
"@id": "{{ .Permalink }}",
"name": "{{ .Title | humanize }}"
}
}]
}
</script>

View file

@ -0,0 +1,47 @@
<script type="application/ld+json"> {
"@context" : "http://schema.org",
"@type" : "BlogPosting",
{{ if .Params.categories }}{{ range .Params.categories }}"articleSection" : "{{ . }}",{{ end }}{{ end }}
"name" : "{{ .Title | safeJS }}",
"headline" : "{{ .Title | safeJS }}",
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "{{ .Permalink }}"
},
"description" : "{{ if .Description }}{{ .Description | plainify }}{{ else }}{{if .IsPage}}{{ .Summary | plainify }}{{ end }}{{ end }}",
"inLanguage" : "{{ .Lang }}",
{{ if .Params.author -}}
"author": {
"@type": "Person",
"name": "{{ .Params.author }}"
},
{{- else if .Site.Params.author.name -}}
"author": {
"@type": "Person",
"name": "{{ .Site.Params.author.name }}"
},
{{- end }}
"copyrightYear" : "{{ .Site.Params.since }} - {{ .Site.Lastmod.Format "2006" }}",
{{ if not .PublishDate.IsZero -}}
"datePublished": "{{ .PublishDate.Format "2006-01-02T15:04:05-07:00" | safeHTML }}",
{{- else if not .Date.IsZero -}}
"datePublished": "{{ .Date.Format "2006-01-02T15:04:05-07:00" | safeHTML }}",
{{- end }}
{{ with .Lastmod -}}
"dateModified": "{{ .Format "2006-01-02T15:04:05-07:00" | safeHTML }}",
{{- end }}
"url" : "{{ .Permalink }}",
"wordCount" : "{{ .WordCount }}",
"image" : "{{ .Params.share_img | default .Params.image | default .Site.Params.logo | absURL }}",
"keywords" : [ "{{ range $i, $e := .Params.tags }}{{ if $i }}, {{ end }}{{ $e }}{{ end }}" ],
"publisher" : {
"@type": "Organization",
"name" : "{{ .Site.BaseURL }}",
"logo" : {
"@type" : "ImageObject",
"url" : "{{ .Site.Params.logo | absURL }}",
"height" : 60 ,
"width" : 60
}
}
} </script>

View file

@ -15,6 +15,7 @@ pre, code {
hr.small { hr.small {
border-width: 5px; border-width: 5px;
border-color: #00a185; border-color: #00a185;
margin-top: 4rem;
} }
h1,h2,h3,h4,h5,h6 { h1,h2,h3,h4,h5,h6 {
@ -129,6 +130,19 @@ footer .copyright {
font-family: "Linux Biolinum O", 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: "Linux Biolinum O", 'Helvetica Neue', Helvetica, Arial, sans-serif;
} }
.thumbApps {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-bottom: 20px;
}
.thumbApps > a {
flex: 1 1 180px;
min-width: 0;
text-decoration: none;
}
.thumbApp { .thumbApp {
background-position: 50% 50%; background-position: 50% 50%;
background-repeat: no-repeat; background-repeat: no-repeat;
@ -137,18 +151,14 @@ footer .copyright {
box-shadow: 0px 0px 10px #555; box-shadow: 0px 0px 10px #555;
font-family: "Linux Biolinum O", 'Helvetica Neue', Helvetica, Arial, sans-serif; font-family: "Linux Biolinum O", 'Helvetica Neue', Helvetica, Arial, sans-serif;
height: 200px; height: 200px;
display: block; display: flex;
float: left; flex-direction: column;
margin-right: 0.5%; justify-content: flex-end;
margin-bottom: 20px; transition: transform 0.2s ease, box-shadow 0.2s ease;
width: 24.5%;
min-width: 149px;
} }
.thumbApps > a:hover .thumbApp {
@media only screen and (max-width: 330px) { transform: translateY(-4px) scale(1.02);
.thumbApp { box-shadow: 0px 8px 20px #444;
min-width: 100%;
}
} }
@media only screen and (max-width: 850px) { @media only screen and (max-width: 850px) {
.avatar-container { .avatar-container {
@ -164,9 +174,10 @@ footer .copyright {
.thumbApp p { .thumbApp p {
background-color: rgba(0,0,0,0.7); background-color: rgba(0,0,0,0.7);
border-bottom: solid 4px #00a185; border-bottom: solid 4px #00a185;
border-radius: 0 0 0 1px;
color: white; color: white;
font-weight: bolder; font-weight: bolder;
margin-top: 123px; margin: 0;
padding: 10px; padding: 10px;
} }
.thumbApp:hover p { .thumbApp:hover p {

4
static/robots.txt Normal file
View file

@ -0,0 +1,4 @@
User-agent: *
Allow: /
Sitemap: https://www.nemunai.re/sitemap.xml