Skip to content

fix(LearningCard): suppress <img> when cardImage is empty/missing#1588

Merged
leecalcote merged 4 commits into
masterfrom
fix/learning-card-empty-banner
May 28, 2026
Merged

fix(LearningCard): suppress <img> when cardImage is empty/missing#1588
leecalcote merged 4 commits into
masterfrom
fix/learning-card-empty-banner

Conversation

@miacycle
Copy link
Copy Markdown
Contributor

Summary

LearningCard rendered <img src={cardImage} /> unconditionally. When cardImage is the empty string, the browser interprets src="" as the current page URL, fails to decode it as an image, and shows a broken-image icon in the decorative bottom-right area of every card without a banner.

This surfaced in Layer5 Cloud's academy view: 12 of 19 published learning paths (intro-*, workshop-*) ship with metadata.banner = "", so every card without an explicit banner asset showed a broken icon.

Fix

  • Gate <CardImage> on truthy cardImage in both the active and disabled (Coming Soon) branches - no <img> rendered when there is no banner.
  • Type cardImage as string | undefined. In practice consumers already pass metadata?.banner, which can be undefined; the type now matches usage.
  • Add alt={title} to the active branch (was missing). Brings it in line with the disabled branch and gives screen readers a label.
  • Add regression tests in src/__testing__/LearningCard.test.tsx covering:
    • banner present → <img> rendered with src and alt
    • cardImage: "" → no <img> (this is the bug being fixed)
    • cardImage: undefined → no <img>
    • disabled branch with empty banner → no <img>

Before/after

Before, with cardImage: "":

<div class="CardImage">
  <img src="" />   <!-- browser renders broken-image icon -->
</div>

After: the CardImage wrapper and its <img> are simply omitted.

Compatibility

  • Backwards-compatible. Callers that previously passed a truthy cardImage render identically.
  • The type widening from string to string | undefined is a relaxation; consumers that were already passing string continue to type-check.

Test plan

  • npx jest src/__testing__/LearningCard.test.tsx - 4/4 pass
  • Full suite npx jest - 277/277 pass, 10 suites
  • npx eslint src/custom/LearningCard/ src/__testing__/LearningCard.test.tsx - clean
  • npx prettier --check ... - clean
  • Consumer verification in layer5io/meshery-cloud after this lands in a sistent release and the dep is bumped (broken icons in academy cards should disappear)

Empty banner values caused <img src=""> to render, which the browser
interprets as the current page URL, fails to decode as an image, and
shows a broken-image icon. This affected academy content cards in
Layer5 Cloud whenever a learning path lacked a banner asset.

- Gate <CardImage> on truthy cardImage in both branches
- Type cardImage as string | undefined (it was already optional in
  practice; callers pass metadata?.banner which may be undefined)
- Add alt={title} to the active branch for consistency with the
  disabled branch and basic a11y
- Add regression tests covering present/empty/undefined banner and
  the disabled branch

Signed-off-by: miacycle <184569369+miacycle@users.noreply.github.com>
Copilot AI review requested due to automatic review settings May 28, 2026 05:48
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request makes the cardImage property optional on LearningCard and conditionally renders the <img> tag only when cardImage is present. This prevents broken-image icons from rendering when the image source is empty or undefined. Additionally, a new test suite has been added to verify this behavior. The review feedback suggests improving accessibility (a11y) by falling back to courseTitle for the image's alt attribute if title is empty or undefined.

Comment thread src/custom/LearningCard/LearningCard.tsx Outdated
Comment thread src/custom/LearningCard/LearningCard.tsx Outdated
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates LearningCard to avoid rendering a broken decorative banner image when cardImage is missing or an empty string, aligning component behavior with real-world consumer data (e.g., academy cards without banners).

Changes:

  • Make cardImage optional and conditionally render the <CardImage> / <img> only when a truthy banner URL is present.
  • Add/adjust alt handling on the banner image and keep behavior consistent across enabled/disabled (“Coming Soon”) branches.
  • Add Jest regression tests covering banner present vs empty/undefined banner, including the disabled branch.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/custom/LearningCard/LearningCard.tsx Makes cardImage optional and gates rendering of the <img> to prevent src="" broken-image behavior.
src/testing/LearningCard.test.tsx Adds regression tests verifying <img> is rendered only when cardImage is provided and omitted for empty/undefined.

</CardImage>
{tutorial.frontmatter.cardImage ? (
<CardImage>
<img src={tutorial.frontmatter.cardImage} alt={tutorial.frontmatter.title} />
</CardImage>
{tutorial.frontmatter.cardImage ? (
<CardImage>
<img src={tutorial.frontmatter.cardImage} alt={tutorial.frontmatter.title} />
Comment thread src/__testing__/LearningCard.test.tsx Outdated
leecalcote and others added 3 commits May 28, 2026 01:13
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Lee Calcote <leecalcote@gmail.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: Lee Calcote <leecalcote@gmail.com>
Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
Signed-off-by: Lee Calcote <leecalcote@gmail.com>
@leecalcote leecalcote merged commit f7f3b40 into master May 28, 2026
2 of 5 checks passed
@leecalcote leecalcote deleted the fix/learning-card-empty-banner branch May 28, 2026 06:14
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.

3 participants