Skip to content

Commit 8865b2f

Browse files
authored
Fix: Auth0-Lock Error with React 19 and Nextjs 15 (#2701)
### Changes Fixes React 19 and NextJS 15 compatibility issues in auth0-lock by removing deprecated APIs that were removed in React 19: - Legacy string refs (`ref="name"`) - `ReactDOM.findDOMNode()` - `react-transition-group` v2 (which used deprecated APIs) **Root Cause:** auth0-lock was using legacy string refs (e.g., `ref="chrome"`) which were removed in React 19 - Closes #[2590](#2590) ### Changes Made #### 1. String Refs → React.createRef() (13 files) Converted all legacy string refs to the modern `createRef()` pattern: **Before (React 18 and earlier):** ``` <Chrome ref="chrome" /> this.refs.chrome.focusError() ``` After (React 19 compatible): ``` constructor(props) { super(props); this.chromeRef = React.createRef(); } <Chrome ref={this.chromeRef} /> this.chromeRef.current.focusError() ``` 2. Removed `ReactDOM.findDOMNode()` Replaced all `ReactDOM.findDOMNode()` calls with direct ref access: Before: ``` const node = ReactDOM.findDOMNode(this); node.focus(); ``` After: ``` const node = this.nodeRef.current; node.focus(); ``` 3. Added nodeRef Props to CSSTransition Added nodeRef props to CSSTransition components to avoid react-transition-group's findDOMNode fallback: Before: ``` <CSSTransition classNames="slide" timeout={350}> {children} </CSSTransition> ``` After: ``` <CSSTransition nodeRef={this.transitionRef} classNames="slide" timeout={350} > <div ref={this.transitionRef}> {children} </div> </CSSTransition> ``` 4. Dependency Upgrades - react-transition-group: 2.2.1 → 4.4.5 (v2 used deprecated React APIs) ### Testing Test Environment: - Next.js 15.2.6 - React 19.2.1 - React DOM 19.2.1 #### Test Scenarios: - Lock widget renders without errors - No "Expected ref to be a function" errors - No "findDOMNode is not a function" errors - No legacy context API warnings - Widget interactions work (typing, tab switching, form submission) * [ ] This change adds unit test coverage * [ ] This change adds integration test coverage * [ ] This change has been tested on the latest version of the platform/language ### Checklist * [x] I have read the [Auth0 general contribution guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md) * [x] I have read the [Auth0 Code of Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md) * [x] All code quality tools/guidelines have been run/followed * [ ] All relevant assets have been compiled
1 parent b3f3681 commit 8865b2f

16 files changed

+114
-84
lines changed

package-lock.json

Lines changed: 26 additions & 45 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
"qs": "^6.10.3",
132132
"react": "^18.2.0",
133133
"react-dom": "^18.2.0",
134-
"react-transition-group": "^2.2.1",
134+
"react-transition-group": "^4.4.5",
135135
"trim": "^1.0.1",
136136
"url-join": "^1.1.0",
137137
"validator": "^13.15.22"

src/__tests__/i18n.test.js

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,8 +59,11 @@ describe('i18n', () => {
5959
};
6060
const m = Immutable.fromJS({ i18n: { strings } });
6161
const html = i18n.html(m, 'test');
62-
expect(html.props.dangerouslySetInnerHTML.__html).not.toMatch(/javascript:alert/);
63-
expect(html.props.dangerouslySetInnerHTML.__html).toEqual('<img href="1" src="1">');
62+
const sanitized = html.props.dangerouslySetInnerHTML.__html;
63+
expect(sanitized).not.toMatch(/javascript:alert/);
64+
expect(sanitized).toMatch(/src="1"/);
65+
expect(sanitized).toMatch(/href="1"/);
66+
expect(sanitized).toMatch(/<img[^>]*>/);
6467
});
6568

6669
it('should allow target=_blank with noopener noreferrer attributes', () => {

0 commit comments

Comments
 (0)