Skip to content

feat(blog): localized post slugs, and the blog in en and es (21/54 posts) - #1682

Merged
AldemirLucas merged 10 commits into
mainfrom
feat/blog-translations
Oct 5, 2026
Merged

AldemirLucas merged 10 commits into
mainfrom
feat/blog-translations

Conversation

@rdahis

@rdahis rdahis commented Sep 9, 2026

Copy link
Copy Markdown
Member

Translates the blog into English and Spanish, and adds the slug mapping that makes localized blog URLs possible.

This branch is in progress: 21 of 54 posts are translated. The remaining 33 will land as further commits on this same branch. It is opened now so the routing change can be reviewed before another 66 files come to depend on it.

The slug mapping (the part worth reviewing)

Posts keep one filename across locales — that filename is what ties a post's translations together — and each translation declares its own public slug in frontmatter.

  • getAllPosts now returns both slug (the URL segment, from frontmatter when present) and filename (shared across locales).
  • getPostBySlug resolves by filename first, then falls back to scanning for the post whose frontmatter declares that slug, so both forms work.
  • The post page redirects the filename form to the locale's own slug. This matters because the language switcher does router.push(router.pathname, router.asPath, { locale }), carrying the current slug across locales — without the redirect, switching language on a post would land on the blog index.
  • getStaticPaths previously generated paths from the Portuguese filenames only, for every locale. It is now locale-aware.
  • The "edit this page" link points at the real file rather than the localized slug.

Resolution was simulated against the real files. For example, with blog/en/curso-qgis.md declaring slug: free-qgis-course:

Request Result
/blog/curso-qgis (pt) renders, unchanged
/en/blog/free-qgis-course renders from blog/en/curso-qgis.md
/en/blog/curso-qgis (what the language switcher produces) redirects to /en/blog/free-qgis-course
/en/blog/<a pt slug with no en translation> redirects to the blog index, as before

No redirect loops.

Translations so far

21 posts in both en and es — 9 analyses, 6 institutional, 5 tutorials, 1 uncategorised.

One of them, analisando-atividade-economica-do-rio-de-janeiro, already had en and es files, but both contained the Portuguese body under a translated frontmatter. Those are rewritten properly.

Conventions applied throughout:

  • SQL, R and Python blocks are verbatim. They reference real BigQuery tables and columns (id_municipio, sigla_uf, id_pais), which the surrounding prose names, so translating an identifier would silently break the tutorial.
  • Brazilian institution and dataset names are kept: IBGE, RAIS, CNAE, INEP, INMET, SINAN, SEBRAE, Comex Stat, geobr, LAI.
  • Values in reais are kept as reais.
  • DB Pro callouts in the English posts use the English brand and the /dbpro URL from feat(bdpro): brand the Pro page as DB Pro on the English site #1680.
  • Portuguese wording is unchanged, including informal usages like "a BD".

Also fixed

The blog table-of-contents heading was hardcoded as "Tabela de conteúdo" in Slug.js, so it rendered in Portuguese on every post in every language. It now reads from a new blog.tableOfContents key, added for all three locales.

Testing

Not built or run — the working tree had no node_modules. Verification was static:

  • Every edited JS file parses under Babel.
  • A script checks each translated post: slug present, slug resolves, filename form redirects to it, no stray Portuguese in prose, and structural parity with the Portuguese source (same count of code blocks and images). All 42 post files pass.

The routing change needs a real next build before merge. Two specifics to look at:

  • getStaticPaths now returns { params, locale } entries rather than bare { params }. That is the documented shape for i18n, but it is the kind of thing worth confirming against an actual build.
  • getPostBySlug's fallback reads every file in the locale directory when the fast path misses. That is fine at 54 posts and static build time, but it is a linear scan.

Known gaps

  • Screenshots and chart images are shared across locales and show Portuguese interfaces (BigQuery, Power BI, QGIS) and Portuguese ggplot axis labels. The prose is translated; the images are not. Localised images would be a separate piece of work.
  • Two translated posts carry published: false in the source (intro-ao-pacote-basedosdados-em-python, como-funciona-o-sistema-de-insercao-de-dados-na-bd). They are translated for parity but stay invisible until that flag changes.
  • relembrando-o-datathon-bd-2021 links to /ufrj-analytica/datathon-open-data-day-..., which looks like a Medium URL missing its domain. Broken in the Portuguese original too; copied as-is rather than guessed at.

Groundwork for translating the blog. Posts keep one filename across locales,
which is what ties a post's translations together, and each translation
declares its own public slug in frontmatter.

- getAllPosts returns both `slug` (the URL segment, from frontmatter when
  present) and `filename` (shared across locales).
- getPostBySlug resolves by filename first, then by the frontmatter slug, so
  both forms work.
- The post page redirects the filename form to the locale's own slug, so the
  language switcher — which carries the current slug across locales — still
  lands on the right page rather than the blog index.
- getStaticPaths now pre-renders every locale rather than only the
  Portuguese filenames.
- The "edit this page" link points at the real file, not the localized slug.

First post translated: the QGIS course, at /en/blog/free-qgis-course and
/es/blog/curso-gratuito-de-qgis. Its DB Pro callouts use the English brand
and the /dbpro URL.
Posts translated to en and es:
- analisando-preco-de-imoveis-em-sao-paulo
- analisando-instituicoes-financeiras-de-operacoes-de-credito
- atualizar-como-funciona-o-sistema-de-insercao-de-dados-na-bd

The blog table-of-contents heading was hardcoded as "Tabela de conteúdo" in
Slug.js, so it rendered in Portuguese on every post in every language. It now
reads from a new blog.tableOfContents key, added for all three locales.

Brazilian institution names (IPEA, GeoSampa, ESTBAN, Caixa) and real values in
reais are kept as-is. DB Pro callouts in the English posts use the English
brand and the /dbpro URL.
- analisando-atividade-economica-do-rio-de-janeiro — this one already had an
  en and an es file, but both were the Portuguese text with a translated
  frontmatter. Rewritten properly in both languages.
- entrevista-bdletter-35-karina-lima
- bdletter-38-retrospectiva2024
- analisando-o-brasil-nas-olimpiadas-2016

SQL and R code blocks are copied verbatim from the source, since they query
real tables and columns. Brazilian institution names (IBGE, RAIS, CNAE, INMET,
SEBRAE) and values in reais are kept. Structural parity with the Portuguese
original was checked per post: same number of code blocks and images.
- relembrando-o-datathon-bd-2021
- nota-risco-de-retrocessos-na-lei-de-acesso-a-informacao
- como-usar-os-diretorios-brasileiros
- como-fazer-uma-analise-geoespacial-com-qgis
- atualizar-intro-ao-pacote-basedosdados-em-python

SQL and Python blocks are copied verbatim, including BigQuery table paths and
column names such as id_municipio and sigla_uf, which are referenced in the
surrounding prose and must match the real schema. Dataset and institution
names (IBGE, Ideb, Finbra, Comex Stat, SISCOMEX, geobr, LAI) are kept.

QGIS interface labels are translated to the terms each locale's QGIS build
uses — "Add Delimited Text Layer" / "Añadir capa de texto delimitado".

13 of 54 posts now translated.
- patchnotes_dez
- ferramenta-traz-mais-acessibilidade-aos-dados-de-impulsionamento-eleitoral-nas-redes
- nota-sobre-divulgacao-dos-dados-do-inep
- como-acessar-dados-da-bd-no-power-bi
- patchnotes_janeiro

The two patch notes posts share an `order: 0` field that pins them to the top
of the blog index; that is preserved so the translated indexes order the same
way as the Portuguese one.

Power BI and BigQuery interface labels are translated to the terms each
locale's build shows. Dataset ids, table names and SQL are verbatim.

18 of 54 posts now translated.
- bdletter-36-online-vs-offline
- bdletter-40-qual-e-a-relacao-entre-a-dengue-e-as-mudancas-climaticas
- analisando-relacao-entre-idhm-e-eleicoes

R code blocks are verbatim, including the BigQuery billing project id and the
ggplot labels, which appear inside the rendered chart images shared across
locales. Academic citations (Heiler, Viana and Santos, 2016) and Brazilian
institution names are kept.

21 of 54 posts translated.
- Updated the logic in getStaticPaths to streamline the extraction of slugs from posts.
- Removed unnecessary mapping of filenames, focusing solely on the locale's own slugs.
@AldemirLucas
AldemirLucas merged commit 5c28b2f into main Oct 5, 2026
2 of 3 checks passed

This branch was successfully deployed

No deployments
staging — 238f6078 Deployed Oct 5, 2026 by AldemirLucas via Cypress E2E Tests #175
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants