reflex-site-shared: canonical override + Streamlit footer link + Try-for-free primary CTA#6521
Conversation
Greptile SummaryThis PR makes two additive changes to
Confidence Score: 4/5Safe to merge; changes are purely additive and do not touch any critical runtime paths. Both changes are additive and backwards-compatible. The A second look at Important Files Changed
Sequence DiagramsequenceDiagram
participant Caller as Blog / Marketing page
participant CMT as create_meta_tags()
participant BMT as _build_meta_tags()
participant DOM as Rendered HTML
Caller->>CMT: title, description, image, url, canonical
CMT->>BMT: "title, description, image_url, url=page_url"
BMT-->>CMT: "[og:url=page_url, twitter:url=page_url, ...]"
CMT->>DOM: "link rel=canonical href=canonical"
Note over DOM: og:url still points to blog post URL<br/>canonical points to migration lander
Reviews (1): Last reviewed commit: "reflex-site-shared: add canonical overri..." | Re-trigger Greptile |
| url=page_url, | ||
| ), | ||
| rx.el.link(rel="canonical", href=page_url), | ||
| rx.el.link(rel="canonical", href=canonical or page_url), |
There was a problem hiding this comment.
og:url / twitter:url out of sync with canonical override
When canonical is set to a different URL (e.g., https://reflex.dev/migration/streamlit), _build_meta_tags still receives url=page_url, so og:url and twitter:url continue to point at the originating blog post. Social crawlers (Facebook, Twitter/X) index og:url independently of <link rel="canonical">, so shares of the blog post will surface the blog URL rather than the canonical migration lander, sending mixed signals that partially undermine the SEO consolidation goal. Consider passing canonical or page_url as the url argument to _build_meta_tags as well, or adding a note in the docstring if the current split is intentional.
| url=page_url, | ||
| ), | ||
| rx.el.link(rel="canonical", href=page_url), | ||
| rx.el.link(rel="canonical", href=canonical or page_url), |
There was a problem hiding this comment.
The expression
canonical or page_url silently falls back to page_url when canonical is an empty string "", which is technically a valid (though meaningless) input. Per the codebase's convention for optional string parameters, an explicit is not None guard avoids the ambiguity and is more defensive.
| rx.el.link(rel="canonical", href=canonical or page_url), | |
| rx.el.link(rel="canonical", href=canonical if canonical is not None else page_url), |
Rule Used: When checking for the existence of a value that co... (source)
Learned From
reflex-dev/flexgen#2444
…er link - create_meta_tags grows an optional `canonical` kwarg so any consumer (blog post, lander) can declare a different canonical URL than the page's own. Default behavior is unchanged when the kwarg is omitted. - Footer Migration column gets a "From Streamlit" entry pointing at /migration/streamlit/, ordered first to surface the most specific target. Pairs with: - reflex-dev/marketing PR adding the /migration/streamlit lander. - reflex-dev/blog PR refreshing /blog/reflex-streamlit with a frontmatter canonical override that consumes the new kwarg. Co-Authored-By: Claude Opus 4.7 (1M context) <[email protected]>
d9c2129 to
0772902
Compare
Summary
Three small changes to
reflex-site-sharedfor the Streamlit migration PR series:meta.create_meta_tagsgrows an optionalcanonicalkwarg. When set, the rendered<link rel="canonical">points at that URL instead of the page's ownurl. Default behavior is unchanged when the kwarg is omitted. The blog companion PR uses this to canonicalize/blog/reflex-streamlitto/migration/streamlit.Footer "Migration" column gets a
From Streamlitentry pointing at/migration/streamlit/, ordered first to surface the most specific Streamlit-alternative target above the broader low-code link.cta_card(bottom CTA on every marketing page) swaps Try-for-free into the primary slot and demotes Book a Demo to the ghost-variant secondary. Affects every marketing-templated page acrossreflex-dev/marketing,reflex-dev/docs, andreflex-dev/blogonce theirreflex-site-sharedlockfiles are bumped. No layout change beyond variant and ordering.Why
The Streamlit lander targets paid-search traffic on "streamlit alternative" intent. That audience self-serves, so the primary CTA across the site should be "Try for free" with Book a Demo as a clearly secondary path.
Pairs with
reflex-dev/marketingPR adding the/migration/streamlitlander.reflex-dev/blogPR refreshing/blog/reflex-streamlitwith a frontmatter canonical override pointing at the new lander.Test plan
create_meta_tags(..., canonical=None)produces the same output as before.create_meta_tags(..., canonical="https://reflex.dev/foo")renders a single<link rel="canonical" href="https://reflex.dev/foo">and no duplicate.cta_cardshows "Try for free" (primary, left) + "Book a Demo" (ghost, right) on every marketing page.🤖 Generated with Claude Code