Skip to content

Conversation

@rikaweb
Copy link

@rikaweb rikaweb commented Dec 3, 2025

PR: fix(react): fallback to default export when variant named export not found

Checkboxes to select

  • This PR follows the Contribution Guide
  • Changelog updated
  • Upgrade guide entry added
  • Manual Test/Other (Please elaborate)
  • Bug fix (non-breaking change which fixes an issue)

Description / Motivation

When using SXA rendering variants in Next.js App Router with XM Cloud, components with params.FieldNames set (e.g., HeroST (Right)) fail to render with error:

Placeholder headless-main contains unknown component HeroST (Right). 
Ensure that a React component exists for it, and that it is registered in your component-map file.

Root Cause

In packages/react/src/components/Placeholder/placeholder-utils.tsx, the component resolution logic looks for a named export matching params.FieldNames (e.g., component.Right). If not found, it throws an error instead of falling back to the default export.

Before:

const renderedComponent =
  exportName && exportName !== DEFAULT_EXPORT_NAME
    ? ((component as ReactModule)[exportName] as ComponentType)  // ❌ No fallback
    : (component as ReactModule).default || ...

Solution

Gracefully fallback to the default export when a named variant export is not found:

const variantComponent =
  exportName && exportName !== DEFAULT_EXPORT_NAME
    ? ((component as ReactModule)[exportName] as ComponentType)
    : undefined;

const defaultComponent =
  (component as ReactModule).default ||
  (component as ReactModule).Default ||
  (component as ComponentType);

// Use variant if found, otherwise fallback to default export
const renderedComponent = variantComponent || defaultComponent;

This allows components to:

  1. Optionally provide named exports for specific variants (e.g., export const Right = ...)
  2. Handle all variants via params.FieldNames prop in the default export

Testing Details

  • Tested with HeroST component and HeroST (Right) variant in XM Cloud
  • Component now renders correctly using default export
  • Component receives params.FieldNames prop to handle variant logic
  • Backwards compatible: existing named exports still work as before

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