-
-
Notifications
You must be signed in to change notification settings - Fork 173
fix: Decode HTML entities in climb and area names #1379
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
fix: Decode HTML entities in climb and area names #1379
Conversation
648450f to
cfebba7
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see that these functions are created, but where are they called? @AnshulJagotra
cfebba7 to
1cd57ac
Compare
|
Thanks @mikeschen, you were right — the safeDecode function was created but not used in the components. |
There was a problem hiding this 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 fixes the rendering of HTML entities in climb and area names throughout the application. Previously, names containing ampersands and other HTML entities were displayed as their encoded forms (e.g., & instead of &).
- Added a
safeDecodeutility function that safely decodes HTML entities in both client-side and server-side rendering contexts - Updated components to decode names before display: ClimbData, Area page, and ClimbListForm
- Ensured consistent rendering across SSR and CSR environments
Reviewed Changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/js/utils.ts | Added safeDecode and decodeAmpersand utility functions for HTML entity decoding |
| src/app/(default)/editArea/[slug]/general/components/climb/ClimbListForm.tsx | Applied safeDecode to climb names in the climb list display and toolbar |
| src/app/(default)/climb/[[...slug]]/components/ClimbData.tsx | Applied safeDecode to climb name in the main heading |
| src/app/(default)/area/[[...slug]]/page.tsx | Applied safeDecode to area names in multiple locations including page actions and metadata |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| export const decodeAmpersand = (s: string): string => { | ||
| if (s == null) return '' | ||
| return s.replace(/&/g, '&') | ||
| } |
Copilot
AI
Oct 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The decodeAmpersand function is exported but never used in the codebase. Since safeDecode provides the same functionality plus additional entity decoding, consider removing this unused export to reduce maintenance burden.
| export const decodeAmpersand = (s: string): string => { | |
| if (s == null) return '' | |
| return s.replace(/&/g, '&') | |
| } |
| if (s == null) return '' | ||
| return s.replace(/&/g, '&') | ||
| } | ||
|
|
||
| export const safeDecode = (s: string): string => { | ||
| if (s == null) return '' |
Copilot
AI
Oct 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use strict equality (===) instead of loose equality (==) for null checks. The current check will match both null and undefined, which may be unintended. Replace with if (s == null || s === undefined) or if (s == null) depending on the intended behavior, but prefer === for consistency with TypeScript best practices.
| if (s == null) return '' | |
| return s.replace(/&/g, '&') | |
| } | |
| export const safeDecode = (s: string): string => { | |
| if (s == null) return '' | |
| if (s === null || s === undefined) return '' | |
| return s.replace(/&/g, '&') | |
| } | |
| export const safeDecode = (s: string): string => { | |
| if (s === null || s === undefined) return '' |
| } | ||
|
|
||
| export const safeDecode = (s: string): string => { | ||
| if (s == null) return '' |
Copilot
AI
Oct 28, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use strict equality (===) instead of loose equality (==) for null checks. Replace with explicit null/undefined checks using strict equality for consistency with TypeScript best practices.
| if (s == null) return '' | |
| if (s === null || s === undefined) return '' |
Fixes #1242
Problem Description
Climb and area names containing ampersands (&) or other HTML entities were rendered incorrectly in the frontend.
Currently, these entities (&, <, >, etc.) were displayed literally instead of being decoded, causing route names and climb/area names to appear incorrectly.
Solution
Added a safeDecode utility function in src/js/utils.ts to safely decode common HTML entities.
Updated the following components to use safeDecode before rendering names:
ClimbData.tsx
Area page (page.tsx)
ClimbListForm.tsx
Ensures proper display in both client-side rendering (CSR) and server-side rendering (SSR).
Idempotent solution: safe even if backend resolves encoding in the future.
Testing
Verified that climb and area names with & or other HTML entities display correctly in the UI.
Verified SSR pages render correctly without crashing.
User-facing changes
Climb and area names now display correctly (& instead of &) on all pages.
Backwards-incompatible changes
None. This change only affects frontend rendering logic; existing data and backend APIs remain unchanged.
Optional / Suggestion
If the backend (REST or GraphQL API) is encoding HTML entities before sending names, it may be preferable to send plain text directly.
Frontend will continue to work safely even if the backend implements this change in the future.