Building my blog, part 5: SEO, languages, and RSS

How I organized SEO and RSS for a bilingual blog: URLs, metadata, hreflang, topic feeds, and what Search Console can actually confirm.

Behind the blogSEORSSHugo
Library with a card catalog, an open book and a window overlooking illuminated homes at night.

Editorial illustration created with AI assistance for this series.

TL;DR Short on time? Click to read the summary.
Publishing is one step. I reviewed how the website appears in search and RSS readers, preserving languages, addresses, and dates without promising indexing results.

An article can open normally in the browser and still present itself incorrectly elsewhere. Its search title may be generic, a Portuguese page may advertise the English feed, or a topic feed may contain every article on the blog.

While reviewing the website, I began looking at these outputs too. Published content needs to remain identifiable outside the layout I designed for it.

Visible identity and metadata have their own roles

On the page, a title and description help people understand where they are. Metadata provides the title, description, URL, and other information used by external services. These fields should agree about the content without repeating the brand in every visible sentence.

Articles in this project use editorial data to generate social metadata and structured information. Review starts with the writing: a specific title, a description explaining the subject, and sections that deliver what was promised. Adding search terms that the article never explains would not help.

Each part of this series has a focus: architecture, reading, publishing, images, or discovery. Links between them help readers follow the story without turning five articles into variations of the same introduction.

Two languages need clear addresses

English articles live under /blog/; Portuguese articles under /pt/blog/. A translationKey relates the files, while language metadata points to the equivalent pages.

A canonical URL identifies the preferred address for that page. hreflang identifies language alternatives. The Portuguese version should not treat English as the only primary page and lose its own identity. Both versions need consistent, corresponding links.

Google’s localized-version documentation explains the relationship between these alternatives. In my workflow, validation of generated files helps identify incorrect translation links before publication.

The sitemap should also reflect what is publicly available. Drafts stay out of normal publication, and a preview should not be treated as the final address.

Requesting indexing does not prove the outcome

Search Console has different stages that can look like one when you focus only on a success message:

EvidenceWhat it establishes
Accepted requestThe request was received.
Page already indexedA version of the page exists in the index.
New crawlGoogle fetched the page again.
Displayed search resultYou can observe how it appeared for that query.

A crawl after an edit does not, by itself, demonstrate that the new description was adopted in the result. It does not guarantee a position for a keyword either. Google explicitly notes that requesting another crawl does not guarantee immediate inclusion or inclusion in the index.

The project includes a routine that reads indexing status for the main pages. It tracks changes and failures; it does not submit a new request or automatically track every future article. The monitored set needs review as the website grows.

RSS is another presentation of the same content

RSS lets people follow publications through a feed reader. They subscribe to an address and receive items without visiting the home page to check for something new.

The general Portuguese feed is at /pt/blog/index.xml; English is at /blog/index.xml. Topic and section pages can also have their own feeds. The scope needs to match the page: someone subscribing to a topic expects articles about that topic.

Identification happens in two layers. HTML advertises the feed through a discovery link, and the XML itself identifies its title, language, link, and self URL. A Portuguese page advertising the English feed would be wrong even if both files were valid XML.

Follow via RSS page showing the English feed URL and Copy address button.
The public English RSS page presents the feed address for that language. Readers subscribe to this URL in their feed application.

View the full-size screenshot

What the feed review needed to check

The template starts with eligible publications and applies the section or topic scope before the fifty-item limit. A less frequent topic therefore does not disappear simply because the fifty newest articles overall cover other subjects.

Drafts, samples, and unlisted content are excluded, as are future publication dates. In production, the filter also excludes content marked noindex. That needs checking in the generated XML as well as in the template.

Within an item, relative images and links need to keep working outside the website. An address relying on the current page can resolve incorrectly in a feed reader. Feed content resolves those references against the article’s URL and includes a cover when available.

Dates have separate meanings too. pubDate records publication and preserves the real offset, such as -0300. When revising a published article, I set lastmod to the date of that change:

# Example of a revision after publication.
date: 2026-10-19T09:00:00-03:00
lastmod: 2026-10-20T10:30:00-03:00

The channel’s lastBuildDate uses the latest modification date among its included items. In this project, editing a file without setting lastmod does not automatically turn the commit date into an editorial date.

Keep a routine I can repeat

Before publishing, I review the title and description, translation, links between parts, and cover metadata. After building, I check URLs, feeds, and which pages entered the publication. Once the version reaches the host, I check the served files.

If I started again, I would organize design and architecture earlier, separating each technology and its purpose. Reviewing SEO and RSS reinforced that lesson: each output has its own job, but all of them need to tell the same story about the content.

The website will keep changing. I want these decisions recorded so I can return to them when a tool, integration, or my own idea of a blog changes.

Also on Figueirego

Back to blog