Skip to content

Conversation

oliverabrahams
Copy link
Contributor

@oliverabrahams oliverabrahams commented Aug 27, 2025

co-authored by @charleycampbell

What does this change?

We're introducing two new product card components, InlineProductCard and LeftColProductCard, along with supporting changes to styling, image handling, and schema updates.

These components are designed to display product information inline and in the left column of articles, with different layouts and palette colours. The changes also include updates to the image sizing logic for product cards and enhancements to the button styling for product links.

New Product Card Components:

  • Added InlineProductCard and LeftColProductCard components to display product information, including brand, product name, image, pricing, retailer links, CTAs, and statistics. Each component has its own layout and styling for different breakpoints.

Styling and Palette Enhancements:

  • Added new palette variables for product card backgrounds and product button backgrounds, including hover states, to ensure consistent theming.

Image Handling:

  • Extended the Picture component to support a new productCard role type, with tailored image sizing logic for product cards at different breakpoints.

Schema Updates:

  • Updated article and block schemas to require and validate an elementId for LinkBlockElement, ensuring unique identification and improved data integrity for product-related links. This was already coming from FE but was missing from the model in DCR. This is a fix and allows us to directly copy elements from FE for ProductElement.stories.tsx

Why?

We are adding in a new element called Product. This product element will help structure the product data and also the ability to display product reviews as part of the new designs. This is the RFC

Screenshots

LeftCol product card
image

@oliverabrahams oliverabrahams added the run_chromatic Runs chromatic when label is applied label Sep 9, 2025
Copy link

github-actions bot commented Sep 9, 2025

@github-actions github-actions bot removed the run_chromatic Runs chromatic when label is applied label Sep 9, 2025
Copy link

github-actions bot commented Sep 9, 2025

oliverabrahams and others added 8 commits September 24, 2025 14:18
- minor tweaks to left col card so its more aligned with the figma
- removed retailer from the price row (TBC)
- reworded cta (this TBC)
- updated storybooks to reflect the likes/dislikes of product
- removed retailer from the price row (TBC)
- reworded cta (this TBC)
- updated storybook to reflect the likes/dislikes of product
- added url cleaner
<div css={productInfoContainer}>{children}</div>
);

const stripHtml = (html: string) => html.replace(/<[^>]+>/g, '');

Check failure

Code scanning / CodeQL

Incomplete multi-character sanitization High

This string may still contain
<script
, which may cause an HTML element injection vulnerability.

Copilot Autofix

AI 2 days ago

General fix approach:
The best way to fix the incomplete multi-character sanitization problem is to use a well-tested library like sanitize-html to strip out HTML tags correctly, as hand-rolled regex-based HTML removal is error-prone and inherently incomplete.

Detailed fix for this code:

  • Replace the current stripHtml implementation with a call to sanitize-html, configured to remove all HTML tags and escape content.
  • Add an import for sanitize-html at the top.
  • Optionally, if external libraries are undesirable, repeatedly apply the regular expression replacement in a loop until the string no longer changes (but this is discouraged in favor of a library).
  • No other parts of the file need to change.

Specific changes to apply:

  • Add import sanitizeHtml from 'sanitize-html'; at the top of the file.
  • Replace the implementation of stripHtml with a function that calls sanitizeHtml(html, { allowedTags: [], allowedAttributes: {} }), which removes all HTML tags.

Suggested changeset 1
dotcom-rendering/src/components/InlineProductCard.tsx

Autofix patch

Autofix patch
Run the following command in your local git repository to apply this patch
cat << 'EOF' | git apply
diff --git a/dotcom-rendering/src/components/InlineProductCard.tsx b/dotcom-rendering/src/components/InlineProductCard.tsx
--- a/dotcom-rendering/src/components/InlineProductCard.tsx
+++ b/dotcom-rendering/src/components/InlineProductCard.tsx
@@ -1,4 +1,5 @@
 import { css } from '@emotion/react';
+import sanitizeHtml from 'sanitize-html';
 import {
 	from,
 	headlineMedium20,
@@ -101,7 +102,7 @@
 	<div css={productInfoContainer}>{children}</div>
 );
 
-const stripHtml = (html: string) => html.replace(/<[^>]+>/g, '');
+const stripHtml = (html: string) => sanitizeHtml(html, { allowedTags: [], allowedAttributes: {} });
 
 export const InlineProductCard = ({
 	format,
EOF
@@ -1,4 +1,5 @@
import { css } from '@emotion/react';
import sanitizeHtml from 'sanitize-html';
import {
from,
headlineMedium20,
@@ -101,7 +102,7 @@
<div css={productInfoContainer}>{children}</div>
);

const stripHtml = (html: string) => html.replace(/<[^>]+>/g, '');
const stripHtml = (html: string) => sanitizeHtml(html, { allowedTags: [], allowedAttributes: {} });

export const InlineProductCard = ({
format,
Copilot is powered by AI and may make mistakes. Always verify output.
<div css={productInfoContainer}>{children}</div>
);

const stripHtml = (html: string) => html.replace(/<[^>]+>/g, '');

Check failure

Code scanning / CodeQL

Polynomial regular expression used on uncontrolled data High

This
regular expression
that depends on
a user-provided value
may run slow on strings starting with '<' and with many repetitions of '<'.
This
regular expression
that depends on
a user-provided value
may run slow on strings starting with '<' and with many repetitions of '<'.
This
regular expression
that depends on
a user-provided value
may run slow on strings starting with '<' and with many repetitions of '<'.
This
regular expression
that depends on
a user-provided value
may run slow on strings starting with '<' and with many repetitions of '<'.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants