Skip to content

no image update#1813

Merged
tgberkeley merged 3 commits intomainfrom
add-new-blogs
Apr 7, 2026
Merged

no image update#1813
tgberkeley merged 3 commits intomainfrom
add-new-blogs

Conversation

@tgberkeley
Copy link
Copy Markdown
Collaborator

No description provided.

@greptile-apps
Copy link
Copy Markdown
Contributor

greptile-apps bot commented Apr 7, 2026

Greptile Summary

This PR adds 40 new SEO-targeted blog posts (all without an image field, all with show_in_cards: false) and updates the blog rendering pipeline to treat the image field as optional throughout. Previously, missing images defaulted to empty strings, producing broken og:image/twitter:image meta tags and invalid JSON-LD structured data that would be flagged by Google Search Console.

Key changes:

  • pcweb/meta/meta.py: _build_meta_tags now only appends og:image / twitter:image when the value is truthy; blog_jsonld conditionally adds "image" to the posting dict; type hints updated to str | None
  • pcweb/pages/blog/blog.py: Blog index card switches to .get("image") or None; the card image container is conditionally rendered via rx.fragment() when no image is present
  • pcweb/pages/blog/page.py: Individual post page mirrors the same conditional image rendering; blog_jsonld call uses .get("image") or None
  • 40 new blog posts covering integrations (Google Auth, Anthropic, Stripe, Snowflake, etc.) — none include an image field, and all opt out of the visible card grid with show_in_cards: false

Confidence Score: 5/5

Safe to merge — all previously identified image-handling issues are properly resolved with no new regressions.

All prior P1 findings (broken og:image/twitter:image tags, invalid JSON-LD image field) are fixed. The new posts are hidden from the card grid via show_in_cards: false, so no layout regressions. No new issues were found across the 43 changed files.

No files require special attention.

Important Files Changed

Filename Overview
pcweb/meta/meta.py Correctly makes image optional: conditionally appends og:image/twitter:image tags and omits the JSON-LD image field when None
pcweb/pages/blog/blog.py Switches to .get('image') or None; conditionally renders card image section with rx.fragment() fallback when no image present
pcweb/pages/blog/page.py Mirrors blog.py pattern: uses meta.get('image') or None for JSON-LD and conditionally renders hero image on the post page
blog/build-dashboard-google-auth.md New SEO blog post without image field; show_in_cards: false keeps it out of the visible card grid
blog/build-dashboard-with-anthropic.md New SEO blog post, consistent frontmatter structure — no image, show_in_cards: false

Sequence Diagram

sequenceDiagram
    participant MD as Blog Post (.md)
    participant BP as blog.py / page.py
    participant MP as marketing_page
    participant Meta as meta.py

    MD->>BP: metadata (no 'image' key)
    BP->>BP: metadata.get('image') or None → None
    BP->>MP: marketing_page(image=None, meta=[...])
    BP->>Meta: create_meta_tags(image=None)
    Meta->>Meta: image_url = None (skip to_cdn_image_url)
    Meta->>Meta: _build_meta_tags(image=None)
    Meta-->>Meta: if image: → False, skip og:image & twitter:image
    Meta-->>BP: tags without og:image / twitter:image
    BP->>Meta: blog_jsonld(image=None)
    Meta->>Meta: image_url = None (skip to_cdn_image_url)
    Meta->>Meta: if image_url: → False, omit 'image' from posting
    Meta-->>BP: valid JSON-LD without image field
    BP->>BP: if meta.get('image'): → False → rx.fragment()
    BP-->>MP: page rendered without image element
Loading

Greploops — Automatically fix all review issues by running /greploops in Claude Code. It iterates: fix, push, re-review, repeat until 5/5 confidence.
Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal.

Reviews (2): Last reviewed commit: "image fix" | Re-trigger Greptile

Comment on lines +208 to +209
date=str(meta["date"]),
image=meta["image"],
image=meta.get("image", ""),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Empty string produces invalid JSON-LD image field

meta.get("image", "") returns "" when no image is present. blog_jsonld in meta.py then calls to_cdn_image_url(""), which returns "" (line 100: return image or ""), and unconditionally assigns "image": "" to the posting dict (line 161). This results in invalid schema.org structured data — an empty string is not a valid URL for the image property — which Google Search Console will flag as a structured data error and which can hurt SEO for imageless posts.

The fix requires two coordinated changes:

  1. Pass None here instead of "":
Suggested change
date=str(meta["date"]),
image=meta["image"],
image=meta.get("image", ""),
image=meta.get("image") or None,
  1. Update blog_jsonld in pcweb/meta/meta.py to conditionally include the image field:
image_url = to_cdn_image_url(image) if image else None
posting: dict = {
    "@type": "BlogPosting",
    "headline": title,
    "description": description,
    "datePublished": str(date),
    "url": url,
    "author": author_node,
}
if image_url:
    posting["image"] = image_url

Comment on lines 228 to 235
title=seo_title,
description=document.metadata["description"],
image=document.metadata["image"],
image=document.metadata.get("image", ""),
meta=create_meta_tags(
title=seo_title,
description=document.metadata["description"],
image=document.metadata["image"],
image=document.metadata.get("image", ""),
url=f"https://reflex.dev{route}",
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Empty string produces broken og:image / twitter:image meta tags

Both image=document.metadata.get("image", "") calls (lines 230 and 234) pass "" to marketing_page and create_meta_tags when no image is present. In create_meta_tags (meta.py line 122), "" is falsy so image_url = "", which is then forwarded to _build_meta_tags. That function unconditionally emits:

<meta property="og:image" content="">
<meta name="twitter:image" content="">

Social media crawlers (Facebook, Twitter/X, LinkedIn) will see these tags, attempt to resolve an empty URL, and render broken or missing share previews — this is actively worse than omitting the tags entirely.

Change both fallbacks from "" to None (or omit them) and update _build_meta_tags in meta.py to skip the image tags when the value is falsy:

# In blog.py (apply to both occurrences)
image=document.metadata.get("image") or None,
# In meta.py _build_meta_tags, replace the two image lines:
*([{"property": "og:image", "content": image}, {"name": "twitter:image", "content": image}] if image else []),

@tgberkeley
Copy link
Copy Markdown
Collaborator Author

@greptile-ai

@tgberkeley tgberkeley merged commit 8260d4e into main Apr 7, 2026
9 of 10 checks passed
@tgberkeley tgberkeley deleted the add-new-blogs branch April 7, 2026 18:05
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