Skip to content

feat(blog): branded placeholder featured image for imageless posts (po-66l)#1645

Merged
anuveyatsu merged 1 commit into
mainfrom
fix/blog-default-featured-image
Jul 7, 2026
Merged

feat(blog): branded placeholder featured image for imageless posts (po-66l)#1645
anuveyatsu merged 1 commit into
mainfrom
fix/blog-default-featured-image

Conversation

@anuveyatsu

@anuveyatsu anuveyatsu commented Jul 7, 2026

Copy link
Copy Markdown
Member

What

Recent blog posts with no image in frontmatter rendered a plain gradient box on /blog. This adds a branded placeholder featured image so every post gets a proper card.

  • New self-contained 1200Γ—630 SVG at site/public/static/img/blog/default-featured.svg β€” PortalJS cyclone mark as hero + orbiting "composable skills" marks, blue gradient, dot texture. Imported from the PortalJS blog featured images Claude Design project.
  • DEFAULT_FEATURED_IMAGE constant; BlogCard, FeaturedBlogPost, MiniCard now fall back to it (blog.image || DEFAULT_FEATURED_IMAGE) instead of the gradient.

Scope

  • og:image unchanged β€” still the site-wide default. SVG isn't well-supported as an og/twitter image; a PNG render of this design for imageless-post og is a sensible follow-up.

πŸ€– Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added a consistent default blog image for posts without a custom image.
    • Updated blog cards, featured posts, and mini cards to always display an image instead of a placeholder block.
  • Bug Fixes

    • Improved visual consistency across blog listings when image data is missing.

…o-66l)

Recent posts with no frontmatter image showed a plain gradient on /blog.
Add a self-contained 1200x630 SVG (PortalJS cyclone + orbiting
composable-skill marks, from the 'PortalJS blog featured images' Claude
Design project) and default BlogCard/FeaturedBlogPost/MiniCard to it via
DEFAULT_FEATURED_IMAGE. og:image unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@changeset-bot

changeset-bot Bot commented Jul 7, 2026

Copy link
Copy Markdown

⚠️ No Changeset found

Latest commit: 2e2cde6

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel

vercel Bot commented Jul 7, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
www.portaljs.com Ready Ready Preview, Comment Jul 7, 2026 5:27pm
7 Skipped Deployments
Project Deployment Actions Updated (UTC)
portaljs-alan-turing Ignored Ignored Preview Jul 7, 2026 5:27pm
portaljs-ckan Ignored Ignored Preview Jul 7, 2026 5:27pm
portaljs-ckan-ssg Ignored Ignored Preview Jul 7, 2026 5:27pm
portaljs-fivethirtyeight Ignored Ignored Preview Jul 7, 2026 5:27pm
portaljs-git-example Ignored Ignored Preview Jul 7, 2026 5:27pm
portaljs-learn Ignored Ignored Preview Jul 7, 2026 5:27pm
portaljs-openspending Ignored Ignored Preview Jul 7, 2026 5:27pm

Request Review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

πŸ“ Walkthrough

Walkthrough

Adds a new DEFAULT_FEATURED_IMAGE constant referencing a placeholder SVG path, and updates BlogCard, FeaturedBlogPost, and MiniCard to render an <img> unconditionally, falling back to this constant when blog.image is absent, replacing the previous gradient placeholder rendering.

Changes

Default featured image fallback

Layer / File(s) Summary
Default image constant
site/components/blog/defaultFeaturedImage.ts
Exports DEFAULT_FEATURED_IMAGE, a path to a placeholder SVG, with a documenting comment.
Blog card and featured post fallback rendering
site/components/blog/BlogCard.tsx, site/components/blog/FeaturedBlogPost.tsx
Import the new constant and replace conditional image/gradient-placeholder rendering with a single <img> using blog.image || DEFAULT_FEATURED_IMAGE.
Mini card fallback rendering
site/components/blog/MiniCard.tsx
Imports the new constant and replaces the gradient placeholder branch with an unconditional <img> using the same fallback logic.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

  • datopian/portaljs#1593: Modifies the same BlogCard, FeaturedBlogPost, and MiniCard components' handling of missing blog.image, originally introducing the conditional gradient placeholder that this PR replaces.

Suggested reviewers: Datopian-Shreyas

πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title accurately summarizes the main change: a branded placeholder featured image for blog posts without images.
Docstring Coverage βœ… Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check βœ… Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check βœ… Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
πŸ“ Generate docstrings
  • Create stacked PR
  • Commit on current branch
πŸ§ͺ Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/blog-default-featured-image

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

πŸ”§ ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed: one or more packages not found in the registry.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

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.

🧹 Nitpick comments (2)
site/components/blog/BlogCard.tsx (1)

52-56: πŸš€ Performance & Scalability | πŸ”΅ Trivial | πŸ’€ Low value

Consider loading="lazy" on listing thumbnails.

BlogCard typically renders many cards in a grid below the fold; adding loading="lazy" avoids eagerly fetching every card's image (including repeated DEFAULT_FEATURED_IMAGE requests for imageless posts).

♻️ Suggested addition
 <img
   src={blog.image || DEFAULT_FEATURED_IMAGE}
   alt={blog.title}
+  loading="lazy"
   className="absolute inset-0 h-full w-full object-cover transition-transform duration-500 group-hover:scale-[1.03]"
 />
πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@site/components/blog/BlogCard.tsx` around lines 52 - 56, Add lazy loading to
the thumbnail image in BlogCard so grid listings do not eagerly fetch every
image. Update the img element that uses blog.image and DEFAULT_FEATURED_IMAGE to
include a lazy-loading hint, keeping the existing alt and className behavior
unchanged.
site/components/blog/MiniCard.tsx (1)

42-46: πŸ“ Maintainability & Code Quality | πŸ”΅ Trivial | πŸ’€ Low value

Duplicated fallback-image logic across BlogCard, FeaturedBlogPost, and MiniCard.

All three components repeat src={blog.image || DEFAULT_FEATURED_IMAGE} with an <img alt={blog.title} className="absolute inset-0 h-full w-full object-cover ..."> shell. Consider extracting a small shared FeaturedImage component accepting image, alt, and className to consolidate the fallback logic, though each call site's sizing/hover classes differ enough that the payoff is modest.

πŸ€– Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@site/components/blog/MiniCard.tsx` around lines 42 - 46, The featured-image
markup and fallback logic are duplicated across BlogCard, FeaturedBlogPost, and
MiniCard, so extract a small shared FeaturedImage component to centralize the
src fallback and img shell. Move the repeated image handling into that component
with props for image, alt, and className, then update the existing call sites to
pass their specific sizing and hover classes while reusing the shared fallback
behavior.
πŸ€– Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@site/components/blog/BlogCard.tsx`:
- Around line 52-56: Add lazy loading to the thumbnail image in BlogCard so grid
listings do not eagerly fetch every image. Update the img element that uses
blog.image and DEFAULT_FEATURED_IMAGE to include a lazy-loading hint, keeping
the existing alt and className behavior unchanged.

In `@site/components/blog/MiniCard.tsx`:
- Around line 42-46: The featured-image markup and fallback logic are duplicated
across BlogCard, FeaturedBlogPost, and MiniCard, so extract a small shared
FeaturedImage component to centralize the src fallback and img shell. Move the
repeated image handling into that component with props for image, alt, and
className, then update the existing call sites to pass their specific sizing and
hover classes while reusing the shared fallback behavior.

ℹ️ Review info
βš™οΈ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 02876e07-94be-46c4-8e4a-183ed88a5fd7

πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between c90db3c and 2e2cde6.

β›” Files ignored due to path filters (1)
  • site/public/static/img/blog/default-featured.svg is excluded by !**/*.svg
πŸ“’ Files selected for processing (4)
  • site/components/blog/BlogCard.tsx
  • site/components/blog/FeaturedBlogPost.tsx
  • site/components/blog/MiniCard.tsx
  • site/components/blog/defaultFeaturedImage.ts

@anuveyatsu anuveyatsu merged commit 165d4ee into main Jul 7, 2026
15 checks passed
@anuveyatsu anuveyatsu deleted the fix/blog-default-featured-image branch July 7, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

1 participant