Skip to content

Commit 50d5339

Browse files
author
Fergus Bisset
committed
fix: remove useRef from ProductCard for full SSR compatibility
- Remove unnecessary useRef that was preventing SSR usage - Change default seed from Date.now() to 0 for SSR consistency - Add SSR documentation with seed usage guidelines - All 58 tests still passing (32 client + 26 SSR) BREAKING: Vector graphics now default to seed=0 instead of Date.now() when no seed is provided. Always provide an explicit seed for production. Fixes: useRef only works in Client Components error in Next.js
1 parent 779fca9 commit 50d5339

File tree

2 files changed

+41
-5
lines changed

2 files changed

+41
-5
lines changed

src/components/ProductCard/ProductCard.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -525,13 +525,13 @@ export const ProductCard: React.FC<ProductCardProps> = ({
525525
elevated = true,
526526
imageAspectRatio = 1.5,
527527
}) => {
528-
const cardRef = React.useRef<HTMLDivElement>(null);
529-
530528
// Generate or use provided shapes
529+
// Note: For SSR compatibility, always provide a seed if using graphic images
530+
// to avoid hydration mismatches from Date.now()
531531
const shapes = React.useMemo(() => {
532532
if (image?.type === "graphic") {
533533
if (image.shapes) return image.shapes;
534-
const seed = image.seed ?? Date.now();
534+
const seed = image.seed ?? 0; // Default to 0 for SSR consistency
535535
const imgTheme = image.theme ?? theme;
536536
return generateVectorShapes(seed, imgTheme);
537537
}
@@ -653,7 +653,6 @@ export const ProductCard: React.FC<ProductCardProps> = ({
653653

654654
return (
655655
<div
656-
ref={cardRef}
657656
className={cardClasses}
658657
style={style}
659658
onClick={onClick || href ? handleCardClick : undefined}

src/components/ProductCard/README.md

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -388,6 +388,43 @@ Themes must be one of the predefined values. To use custom colors, apply them vi
388388
/>
389389
```
390390

391+
## Server-Side Rendering (SSR)
392+
393+
ProductCard is fully SSR-compatible and can be imported from the `/ssr` barrel:
394+
395+
```tsx
396+
import { ProductCard, ProductCardThemeEnum } from '@fergusbisset/nhs-fdp-design-system/ssr';
397+
```
398+
399+
### Important SSR Considerations
400+
401+
When using vector graphics with SSR (Next.js, Remix, etc.), **always provide a seed value** to ensure consistent rendering between server and client:
402+
403+
```tsx
404+
// ✅ Good - Consistent SSR
405+
<ProductCard
406+
image={{
407+
type: 'graphic',
408+
seed: 12345, // Same shapes on server and client
409+
theme: 'blue'
410+
}}
411+
title="My Product"
412+
description="Description"
413+
/>
414+
415+
// ❌ Avoid - Hydration mismatch
416+
<ProductCard
417+
image={{
418+
type: 'graphic',
419+
// No seed = defaults to 0, but shapes change if seed is added later
420+
}}
421+
title="My Product"
422+
description="Description"
423+
/>
424+
```
425+
426+
**Why this matters**: Without a seed, the shape generation defaults to `0` for SSR consistency. If you later rely on dynamic seeds or change the implementation, it could cause hydration mismatches. Always be explicit with your seed values.
427+
391428
## Contributing
392429

393430
When contributing to ProductCard:
@@ -396,7 +433,7 @@ When contributing to ProductCard:
396433
2. Maintain accessibility standards
397434
3. Update documentation for new props
398435
4. Test across major browsers
399-
5. Ensure SSR compatibility
436+
5. Ensure SSR compatibility (no client-only hooks like useRef)
400437

401438
## License
402439

0 commit comments

Comments
 (0)