Skip to content

Commit 7bf9cc0

Browse files
committed
fix: 18n issues and a drift release number in package.json
1 parent 273bba8 commit 7bf9cc0

12 files changed

Lines changed: 215 additions & 89 deletions

File tree

README.md

Lines changed: 183 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,112 +1,214 @@
1-
# vanityURLs — combined patch
1+
# ![Logo](.github/header.png "Logo")
22

3-
Generated: 2026-04-23
3+
![GitHub Stars](https://img.shields.io/github/stars/vanityURLs/website?style=flat-square&logoColor=186ADE&labelColor=3E5462&color=C25100)
4+
![GitHub forks](https://img.shields.io/github/forks/vanityURLs/website?style=flat-square&logoColor=186ADE&labelColor=3E5462&color=C25100)
5+
![GitHub Last Commit](https://img.shields.io/github/last-commit/vanityURLs/website?style=flat-square&logoColor=186ADE&labelColor=3E5462&color=C25100)
6+
![GitHub licence](https://img.shields.io/github/license/vanityURLs/website?style=flat-square&logoColor=186ADE&labelColor=3E5462&color=C25100)
47

5-
This patch set supersedes the earlier `vanityurls-i18n-patch.zip`. It bundles everything into a single delta against your current repo, so you only need to apply one thing.
8+
The source for [vanityURLs.link](https://vanityurls.link) — bilingual (EN/FR) documentation site built with Hugo and deployed on Cloudflare Pages.
69

7-
## What this package contains
10+
## Requirements
811

9-
Two things:
12+
- **Hugo** 0.158.0+ (extended edition). Production is pinned to **0.160.1** in `build.sh`; `hugo.yaml` declares `min_version: 0.158.0`.
13+
- **Node.js** 20+ (production uses 24.14.1). Needed for Tailwind/PostCSS and pagefind.
14+
- **Go** 1.23+ (production uses 1.26.1). Needed for Hugo modules.
1015

11-
- **This directory** — mirrors your `website/` layout. Extract over your working copy.
12-
- **`vanityurls-audit-fixes.diff`** (sibling file) — unified diff; apply with `git apply` or `patch -p1`.
13-
14-
## Summary — what changed and why
15-
16-
### Round 1: i18n URL bug fix + data-driven homepage text
17-
18-
The site had `defaultContentLanguageInSubdir: true` (English at `/en/`) but layouts treated English as living at `/`. Every English sidebar and breadcrumb linked to non-existent `/docs/...` paths. All fixed with `relLangURL`. Homepage conditional strings moved to `data/home.{en,fr}.yml`; "In this section" heading moved to `data/docs_index.{en,fr}.yml`. The `translationKey:` lines were stripped from all content (Hugo pairs translations by basename already).
19-
20-
### Round 2: audit fixes — critical, high, and selected medium/low findings
21-
22-
**Critical**
16+
```bash
17+
brew install hugo node # macOS
18+
npm install # install devDependencies
19+
```
2320

24-
- **RSS feed was broken.** Every `index.xml` started with `<?xml` (HTML-entity-escaped XML declaration). Feed readers rejected it. Deleted the custom `layouts/_default/rss.xml` — Hugo's internal RSS template works correctly.
25-
- **`/security/`, `/trust/`, `/privacy/`, etc. were unreachable.** `security.txt` pointed at `/security/` but the site only has `/en/security/`. Added 18 new redirect rules to `static/_redirects`.
26-
- **`security.txt` pinned Trust Center to `/en/trust/`.** Changed to language-neutral `/trust/` which now redirects.
27-
- **`layouts/_default/single.html` missing dark-mode classes.** 9 legal/info pages (accessibility, contributing, impressum, license, privacy, security, terms, vulnerability, 404) rendered with `text-gray-900` and no `prose-invert` in dark mode. Added `dark:text-gray-100` and `dark:prose-invert`.
28-
- **`<script>` block after `</html>` in `baseof.html`.** ~115 lines of keyboard-nav JS lived outside the document. Moved inside `</body>`.
29-
- **Search modal duplicated.** `search-modal.html` partial was included from both `baseof.html:36` and `header.html:154`, producing duplicate `id` attributes on every page. Removed from header.
21+
## Local development
3022

31-
**High**
23+
```bash
24+
npm run dev # hugo server with drafts
25+
npm run dev:search # same + build pagefind index first (needed for ⌘K)
26+
npm run build # production: hugo --gc --minify && pagefind
27+
npm run clean # remove public/ and resources/_gen/
28+
```
3229

33-
- **Tag pages showed English "post/posts" in French** (`layouts/tags/list.html`). Replaced with `{{ i18n "tag_post_count" (dict "Count" ...) }}` and added pluralized keys in both i18n files.
34-
- **Tags index H1 was hardcoded English** (`layouts/tags/taxonomy.html`). Replaced with `{{ i18n "tags_title" }}` → "Étiquettes" in French.
35-
- **Date formats hardcoded US-style** ("Jan 2, 2006") across four layouts. Now uses `.Date.Format (i18n "date_format_long")`. FR renders "2 Jan 2026".
36-
- **Search JS had three hardcoded English strings** (`baseof.html`: "Run npm run index...", "Search error...", "No results for..."). All now `{{ i18n ... | jsonify }}`.
37-
- **Hardcoded English `aria-label` strings** across 8 layouts: "Toggle menu", "Share on X", "Share on LinkedIn", "Copy link", "Copy code", "Breadcrumb", "Page navigation", "Post navigation", "Blog pagination", "Link to this section". All i18n'd.
38-
- **`build.sh` didn't run pagefind** — search index went stale whenever content changed without a local `npm run build`. Added `npx pagefind --site public` step.
39-
- **`static/pagefind/` was committed** (912 KB of generated output). Removed from repo; added to `.gitignore` (along with `public/`).
30+
The pagefind index (`public/pagefind/`) is generated by the build. Don't commit `static/pagefind/` — it's in `.gitignore`.
4031

41-
**Medium/Low**
32+
## Linting
4233

43-
- **`$lang` variable set but unused** in `footer.html`. Removed.
44-
- **PWA `start_url` was `/`.** With defaultContentLanguageInSubdir, launching the installed PWA triggered a redirect. Changed to `/en/`.
45-
- **Version-infrastructure dead weight.** `data/version.yml` was never read, `layouts/partials/version-banner.html` was a 1-line stub, and `release-please-config.json` was bumping `data/version.yml` on every release for nothing. Removed all three.
46-
- **404 pages had no `description`** in front matter. Added.
47-
- **`package.json` build scripts misaligned with `build.sh`** (the old `cp -r public/pagefind static/` step became obsolete). Cleaned up.
34+
```bash
35+
npm run lint # markdown + yaml + spell
36+
npm run lint:md:fix # auto-fix markdown
37+
npm run lint:links # lychee link checker
38+
npm run lint:secrets # gitleaks secret scanner
39+
```
4840

49-
## Deletions
41+
## Key features
42+
43+
### Documentation
44+
- Multi-level sidebar driven by `data/{en,fr}/docs_nav.yaml` — paths are language-neutral
45+
- Table of contents, breadcrumbs, Edit-on-GitHub, prev/next, mobile `<select>` dropdown
46+
47+
### Blog
48+
- Featured post via `featured: true` front matter (one per language)
49+
- Reading progress bar, social share (X, LinkedIn, copy-link), related posts, tags, RSS
50+
51+
### Showcase
52+
- Client-side tag filter with count badges
53+
54+
### i18n
55+
- Bilingual content: `page.en.md` / `page.fr.md` side-by-side
56+
- UI strings in `i18n/en.yaml` and `i18n/fr.yaml` (45+ keys with pluralization)
57+
- Localized dates via `date_format_long` i18n key
58+
- Language-neutral data file paths (layouts prepend `/en/` or `/fr/` via `relLangURL`)
59+
- Language switcher preserves current page when translation exists
60+
61+
### UX / Accessibility
62+
- Dark mode with no-flash-on-load
63+
- Copy-to-clipboard on every `<pre>`
64+
- ⌘K search via Pagefind
65+
- Skip-to-content link, arrow-key sidebar nav, anchor hover
66+
67+
### SEO / Performance
68+
- hreflang, Open Graph, JSON-LD (SoftwareApplication, TechArticle, BreadcrumbList)
69+
- Favicon + apple-touch-icon from `/logo.svg`
70+
- Language-scoped PWA manifest
71+
- Fingerprinted + minified CSS with SRI
72+
73+
## Shortcodes
74+
75+
```markdown
76+
{{< callout type="warning" title="Breaking change" >}}
77+
This option was removed in v2.
78+
{{< /callout >}}
79+
80+
{{< code file="config/deploy.yml" lang="yaml" >}}
81+
service: my-app
82+
{{< /code >}}
83+
84+
{{< details title="Why not Kubernetes?" >}}
85+
Kubernetes is overkill for most teams.
86+
{{< /details >}}
87+
88+
{{< cards cols="3" >}}
89+
{{< card title="Installation" icon="download" href="/docs/installation/" >}}
90+
Get up and running in minutes.
91+
{{< /card >}}
92+
{{< /cards >}}
93+
94+
{{< filetree/container >}}
95+
{{< filetree/folder name="config" >}}
96+
{{< filetree/file name="deploy.yml" annotation="// edit this" >}}
97+
{{< /filetree/folder >}}
98+
{{< /filetree/container >}}
99+
```
50100

51-
The zip can't convey file removals. These are also handled by the `.diff` if you apply that instead:
101+
Available: `callout`, `code`, `card` + `cards`, `details`, `filetree/*`.
52102

53-
```
54-
rm layouts/_default/trustv0.html
55-
rm layouts/_default/rss.xml
56-
rm layouts/partials/docs-sidebar.html
57-
rm layouts/partials/version-banner.html
58-
rm data/version.yml
59-
rm -rf static/pagefind/
60-
```
103+
## Adding content
61104

62-
## Applying the patch
105+
### New blog post
63106

64-
**Option A — extract over working copy:**
65107
```bash
66-
unzip -o vanityurls-patch.zip -d /path/to/your/website/
67-
# Then run the deletions above
108+
hugo new content blog/my-post.en.md
109+
hugo new content blog/my-post.fr.md
68110
```
69111

70-
**Option B — apply the diff (handles deletions automatically):**
71-
```bash
72-
cd /path/to/your/website/
73-
git apply /path/to/vanityurls-audit-fixes.diff
112+
Front matter:
113+
114+
```yaml
115+
title: "My Post Title"
116+
date: 2026-01-15
117+
author: "Benoît H. Dicaire"
118+
description: "One-sentence description for cards and meta."
119+
tags: ["guide"]
120+
featured: false
74121
```
75122
76-
## Validation
123+
Set exactly one post as `featured: true` per language.
77124

78-
```bash
79-
npm install
80-
hugo --gc --minify && npx pagefind --site public
125+
### New showcase entry
81126

82-
# Round 1 — URLs should all be language-prefixed
83-
grep -oE 'href=[^ >]*docs[^ >]*' public/en/docs/getting-started/index.html | sort -u
84-
# Expect: /en/docs/..., never bare /docs/...
127+
```yaml
128+
title: "My Company"
129+
description: "What they do and why they use vanityURLs."
130+
site_url: "https://example.com"
131+
color: "#0369a1"
132+
logo_char: "M"
133+
tags: ["personal"]
134+
featured: false
135+
```
85136

86-
# Round 2 — RSS declaration should not be escaped
87-
head -c 60 public/en/blog/index.xml
88-
# Expect: <?xml version="1.0" ... (NOT &lt;?xml)
137+
### New docs page
89138

90-
# Round 2 — tag page should show French plural in FR
91-
grep -oE '>\s*[0-9]+\s*article[s]?\s*<' public/fr/tags/guide/index.html
92-
# Expect: >3 articles< (or similar), not "posts"
139+
1. Create `content/docs/my-section/my-page.{en,fr}.md` with `title`, `description`, `nav_order`.
140+
2. Register in both `data/en/docs_nav.yaml` and `data/fr/docs_nav.yaml`. Paths are language-neutral:
93141

94-
# Round 2 — privacy page should be dark-mode styled
95-
grep -c "prose-invert" public/en/privacy/index.html
96-
# Expect: ≥ 1
142+
```yaml
143+
- title: My New Page
144+
url: /docs/my-section/my-page/
145+
children:
146+
- title: Sub-topic
147+
url: /docs/my-section/my-page/sub-topic/
97148
```
98149

99-
## Things NOT addressed in this patch
150+
## Deployment
151+
152+
Cloudflare Pages via `wrangler.toml`. Build command is `./build.sh`, which installs pinned Dart Sass / Go / Hugo / Node.js and then runs `hugo build --gc --minify` followed by `npx pagefind --site public`. Assets directory is `./public`; custom domain is `vanityurls.link`.
153+
154+
See the [Hugo on Cloudflare guide](https://gohugo.io/host-and-deploy/host-on-cloudflare/) for context.
155+
156+
## Project layout
157+
158+
```text
159+
.
160+
├── hugo.yaml # Site config
161+
├── build.sh # Cloudflare Pages build script
162+
├── tailwind.config.js
163+
├── postcss.config.js
164+
├── wrangler.toml
165+
166+
├── assets/css/main.css
167+
168+
├── i18n/
169+
│ ├── en.yaml # English UI strings
170+
│ └── fr.yaml # French UI strings
171+
172+
├── data/
173+
│ ├── en/docs_nav.yaml # English sidebar (language-neutral paths)
174+
│ ├── fr/docs_nav.yaml # French sidebar (same paths, French titles)
175+
│ ├── home.{en,fr}.yml
176+
│ ├── trust.{en,fr}.yml
177+
│ └── docs_index.{en,fr}.yml
178+
179+
├── layouts/
180+
│ ├── index.html
181+
│ ├── 404.html
182+
│ ├── _default/ # baseof, single, taxonomy, trust
183+
│ ├── blog/ # list + single
184+
│ ├── docs/ # list + single
185+
│ ├── showcase/ # list + single
186+
│ ├── tags/ # list + taxonomy
187+
│ ├── shortcodes/ # callout, code, card, cards, details, filetree/*
188+
│ └── partials/ # head, header, footer, search*, jsonld, lang-switcher
189+
190+
├── content/ # .en.md and .fr.md pairs throughout
191+
│ ├── blog/
192+
│ ├── docs/
193+
│ ├── showcase/
194+
│ └── trust/accessibility/impressum/license/privacy/security/terms/vulnerability/contributing
195+
196+
├── static/
197+
│ ├── _headers # CSP + cache rules
198+
│ ├── _redirects # Short-path 301s
199+
│ ├── logo.svg
200+
│ ├── social.png
201+
│ ├── site.webmanifest
202+
│ └── .well-known/security.txt
203+
204+
└── .github/workflows/
205+
└── release-please.yml # Conventional commits → changelog + version
206+
```
100207

101-
From the audit (graded as lower priority or out of scope):
208+
## Contributing
102209

103-
- `_default/taxonomy.html` only renders a stub if you add a new taxonomy — kept it in place with dark-mode classes rather than deleting it.
104-
- Asymmetric `aliases:` (EN has `/a11y`, `/imprint`, `/disclosure` shortcuts; FR doesn't).
105-
- Inconsistency between GitHub `CONTRIBUTING.md` and site `/contributing/`.
106-
- `CONTRIBUTING.md` structure review.
107-
- `wrangler.toml` vs `hugo.yaml` domain casing.
108-
- Security.txt `Expires` date annual-rotation reminder.
210+
For major changes, please open an issue first. See [contribution guidelines](.github/CONTRIBUTING.md) and [code of conduct](.github/CODE_OF_CONDUCT.md).
109211

110-
## Hugo version note
212+
## License
111213

112-
Your `build.sh` installs Hugo 0.160.0. Templates use `css.PostCSS` which is a Hugo 0.128+ API. Worth updating your project notes to reflect 0.160, not 0.123.7, as the required version — 0.123.7 doesn't build this site.
214+
Copyright © 2026 Benoît H. Dicaire. Licensed under the [MIT license](https://choosealicense.com/licenses/mit/). See [LICENSE.md](.github/LICENSE.md).

build.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ main() {
2626
# Define tool versions
2727
DART_SASS_VERSION=1.99.0
2828
GO_VERSION=1.26.1
29-
HUGO_VERSION=0.160.0
29+
HUGO_VERSION=0.160.1
3030
NODE_VERSION=24.14.1
3131

3232
# Set the build timezone

content/accessibility.en.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
---
22
title: "Accessibility Statement"
33
description: "Our commitment to making vanityURLs.link usable by everyone, current WCAG 2.1 compliance status, and how to report accessibility issues."
4-
aliases: a11y
4+
aliases:
5+
- a11y
56
---
67
{{< callout type="note" title="Last reviewed: April 2026" >}}
78
it applies only to the current website (e.g., `vanityURLs.link`) and not to self-hosted vanityURLs deployments.

content/accessibility.fr.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
---
22
title: "Déclaration d'accessibilité"
33
description: "Notre engagement à rendre vanityURLs.link utilisable par tous, le statut de conformité WCAG 2.1, et comment signaler des problèmes d'accessibilité."
4+
aliases:
5+
- accessibilite
6+
- a11y
47
---
58

69
*Dernière révision : avril 2026*

content/impressum.en.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
---
22
title: "Impressum"
33
description: "Legal notice and site operator information for vanityURLs.link, as required for users in Germany, Austria, and Switzerland."
4-
aliases: imprint
4+
aliases:
5+
- imprint
56
---
67
{{< callout type="note" title="Last reviewed: April 2026" >}}
78
{{< /callout >}}

content/impressum.fr.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
---
22
title: "Mentions légales (Impressum)"
33
description: "Mentions légales et informations sur l'opérateur du site vanityURLs.link, conformément aux obligations des utilisateurs en Allemagne, Autriche et Suisse."
4+
aliases:
5+
- mentions-legales
6+
- imprint
47
---
58

69
*Ces mentions légales (Impressum) sont fournies conformément au § 5 DDG (Digitale-Dienste-Gesetz, Allemagne), au § 5 ECG (E-Commerce-Gesetz, Autriche) et aux obligations de transparence équivalentes pour les utilisateurs des pays germanophones.*

content/vulnerability.en.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
---
22
title: "Reporting a Vulnerability"
33
description: "How to report security vulnerabilities in vanityURLs."
4-
aliases: disclosure
4+
aliases:
5+
- disclosure
56
---
67
{{< callout type="tip" title="If you discover a security vulnerability in vanityURLs" >}}
78
Please report it responsibly with _[GitHub Security Advisories](https://github.com/vanityURLs/vanityURLs/security/advisories/new)_

content/vulnerability.fr.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
---
22
title: "Signaler une vulnérabilité"
33
description: "Comment signaler des vulnérabilités de sécurité dans vanityURLs."
4+
aliases:
5+
- divulgation
6+
- disclosure
47
---
58
Si vous découvrez une vulnérabilité de sécurité dans vanityURLs, veuillez la signaler de manière responsable.
69

hugo.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
baseURL: "https://vanityurls.link/"
22
title: "vanityURLs"
33

4+
# Requires Hugo 0.158.0 or newer (uses css.Build and css.PostCSS APIs introduced in 0.158).
5+
# Production is pinned to 0.160.1 in build.sh.
6+
min_version: "0.158.0"
7+
48
enableRobotsTXT: true
59
disableHugoGeneratorInject: false
610

layouts/_default/baseof.html

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -262,7 +262,9 @@
262262
})();
263263
</script>
264264

265-
<!-- Mermaid diagrams -->
265+
{{/* Mermaid diagrams — only loaded when a page actually uses the shortcode.
266+
`.HasShortcode "mermaid"` keeps the CDN call off every page. */}}
267+
{{ if .HasShortcode "mermaid" }}
266268
<script src="https://cdn.jsdelivr.net/npm/mermaid@10/dist/mermaid.min.js" defer></script>
267269
<script>
268270
document.addEventListener('DOMContentLoaded', function() {
@@ -288,6 +290,7 @@
288290
};
289291
});
290292
</script>
293+
{{ end }}
291294

292295

293296
<script>

0 commit comments

Comments
 (0)