Skip to content

Add canonical URL support for posts that also live on posit.co/blog - #367

Open
gregswinehart wants to merge 1 commit into
mainfrom
gs/canonicle
Open

Add canonical URL support for posts that also live on posit.co/blog#367
gregswinehart wants to merge 1 commit into
mainfrom
gs/canonicle

Conversation

@gregswinehart

@gregswinehart gregswinehart commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

What this does

Some of our blog posts are published in two places: here on the open source site and on posit.co/blog. When the same article exists at two URLs, search engines like Google have to guess which one is the "real" version — and they may split ranking credit between the two copies, or show the wrong one in search results.

The fix is a standard web mechanism called a canonical URL: an invisible tag in the page's code that tells search engines "this is the official home of this content — send all the search credit there." Readers never see it; only search engine crawlers do.

How it works now

  • By default, every page on this site declares itself as the official version. No action needed from post authors — this happens automatically.

  • When posit.co's copy should be the official version, the post author adds one line to the post's metadata:

    canonical_url: https://posit.co/blog/name-of-the-post/

    The page then tells search engines to treat the posit.co version as the real one, and our copy stops competing with it in search results. The post itself still displays normally on our site for anyone who visits.

What changed technically

  • layouts/partials/head.html — every page now emits a <link rel="canonical"> tag (self-referencing by default, or pointing at canonical_url when set). The site previously emitted no canonical tags at all.
  • layouts/partials/jsonld.html — the structured data we provide to search engines for blog posts now uses the same canonical URL, so both signals agree.
  • content/blog/CLAUDE.md — the new field is documented in the blog metadata reference.

One limitation to know about

This only covers the case where posit.co's copy is the official one. For the reverse — where our copy should be official — the tag has to be added on posit.co's side, which is outside this repo. That needs coordination with whoever manages posit.co.

How it was tested

Ran a full production build: a post with canonical_url set correctly pointed its canonical tag and structured data at the posit.co URL, and posts without it correctly pointed at themselves.

🤖 Generated with Claude Code


What post goes where?

Most of the historical posts @cwickham brought over to the open source blog are strictly open source themed. Claude found a couple that should probably point to posit.co as the canonical link:

I scanned all 999 posts three ways: paid-product terms in title/description/software fields, mention density in body text, and a loose title sweep (which mostly caught false positives like "Databricks Connect" and "joining the ggplot2 team"). Then I checked which candidates actually exist on posit.co/blog, since canonical_url has to point at a real page.

Recommend adding canonical_url (verified live on posit.co):

  1. Post: Shiny Server (Pro) 1.4.6
    https://opensource.posit.co/blog/2016-09-22_shiny-server-1-4-6/
    https://posit.co/blog/shiny-server-1-4-6
  1. Post: Integrating Dynamic R and Python Models in Tableau Using plumbertableau
    https://opensource.posit.co/blog/2021-12-20_dynamic-r-and-python-models-in-tableau-using-plumbertableau/
    https://posit.co/blog/dynamic-r-and-python-models-in-tableau-using-plumbertableau

Both are judgment calls worth a sanity check from you: the Shiny Server post covers the open-source server and Pro, but its substance is Pro security fixes. The plumbertableau post is about an open-source package, but the entire workflow it describes runs on RStudio Connect (mentioned 10 times).

Fit the "paid product" rule but have no posit.co/blog copy to point at:

  1. Post: Teaching online with RStudio Cloud
    https://opensource.posit.co/blog/2020-04-01_teaching-with-rstudio-cloud-q-a/
    https://education.rstudio.com/blog/2020/04/teaching-with-rstudio-cloud-q-a/
  1. Post: Upcoming changes to RStudio Cloud pricing
    https://opensource.posit.co/blog/2020-07-14_cloud-plans/
    https://education.rstudio.com/blog/2020/07/cloud-plans/

Everything else that mentioned Connect/Workbench/Cloud (pins, blastula, mirai, mcptools, Quarto 1.9, Positron releases, bslib, reprex, etc.) is clearly about open-source software with the paid product as a passing deployment mention — those stay ours.

Every page now emits a self-referencing <link rel="canonical"> tag by
default. Posts whose canonical version lives elsewhere (e.g. the same
post on posit.co/blog) can set canonical_url in frontmatter to point
the canonical tag and blog JSON-LD there instead.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@netlify

netlify Bot commented Jul 31, 2026

Copy link
Copy Markdown

Deploy Preview for posit-open-source canceled.

Name Link
🔨 Latest commit c2cad7f
🔍 Latest deploy log https://app.netlify.com/projects/posit-open-source/deploys/6a6d011b3ab29200085c66e7

@github-actions

Copy link
Copy Markdown
Contributor

Publishing checklist

  • Get a review — you're responsible for requesting one. Any colleague with Write access can approve; if your PR touches files outside a post folder, the assigned code owner's approval is also required before merging
  • Check your post — once the deploy preview is ready, a comment will appear with direct links to your post
  • Check the blog listing — confirm your post appears with the correct title, image, and description
  • Merge — once everything looks good and you have an approving review, merge to main

@github-actions

Copy link
Copy Markdown
Contributor

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.

1 participant