amplify-ui
amplify-ui copied to clipboard
Issue with `withAuthenticator` hook integration in Next.js app
Before creating a new issue, please confirm:
- [X] I have searched for duplicate or closed issues and discussions.
- [X] I have tried disabling all browser extensions or using a different browser
- [X] I have tried deleting the node_modules folder and reinstalling my dependencies
- [X] I have read the guide for submitting bug reports.
On which framework/platform are you having an issue?
React
Which UI component?
Authenticator
How is your app built?
Next.js
What browsers are you seeing the problem on?
Chrome
Which region are you seeing the problem in?
ap-southeast-2
Please describe your bug.
When attempting to integrate the withAuthenticator hook into my basic Next.js application, I encountered an error. I wrapped the root layout of the app with withAuthenticator, but it resulted in an error. I understand that Amplify UI components are client-based, so I also tried using the useClient hook in the pages component, but still no luck.
What's the expected behaviour?
I expected the integration of the withAuthenticator hook to work seamlessly without any errors in the node modules.
Help us reproduce the bug!
- Create a basic Next.js application.
- Run the following commands
npm install aws-amplify @aws-amplify/ui-react&npm install -g @aws-amplify/cli - Wrap the
layout.tsxwithwithAuthenticatorhook. - Then run the server.
Code Snippet
layout.tsx
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import { Amplify } from 'aws-amplify';
import type { WithAuthenticatorProps } from '@aws-amplify/ui-react';
import { withAuthenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import config from './amplifyconfiguration.json';
Amplify.configure(config);
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Dashboard App",
description: "Generated by create next app",
};
const RootLayout = ({ children }: Readonly<{ children: React.ReactNode }>) => {
return (
<html lang="en">
<body className={inter.className}>
{/* Render authenticated content */}
{children}
</body>
</html>
);
}
export default withAuthenticator(RootLayout) as React.ComponentType<WithAuthenticatorProps>;
page.tsx
"use client"
import Image from "next/image";
import {
WithAuthenticatorProps,
withAuthenticator,
} from "@aws-amplify/ui-react";
export function Home() {
return (
<>
Home Page
</>
);
}
export default withAuthenticator(Home) as React.ComponentType<WithAuthenticatorProps>;
Console log output
⨯ ./node_modules/@aws-amplify/ui-react-core/dist/esm/components/FormCore/FormProvider.mjs
Attempted import error: 'useForm' is not exported from 'react-hook-form' (imported as 'useForm').
Import trace for requested module:
./node_modules/@aws-amplify/ui-react-core/dist/esm/components/FormCore/FormProvider.mjs
./node_modules/@aws-amplify/ui-react-core/dist/esm/index.mjs
./node_modules/@aws-amplify/ui-react/dist/esm/index.mjs
./app/layout.tsx
⨯ ./node_modules/@aws-amplify/ui-react-core/dist/esm/components/FormCore/FormProvider.mjs
Attempted import error: 'useForm' is not exported from 'react-hook-form' (imported as 'useForm').
Import trace for requested module:
./node_modules/@aws-amplify/ui-react-core/dist/esm/components/FormCore/FormProvider.mjs
./node_modules/@aws-amplify/ui-react-core/dist/esm/index.mjs
./node_modules/@aws-amplify/ui-react/dist/esm/index.mjs
./app/layout.tsx
⨯ ./node_modules/@aws-amplify/ui-react-core/dist/esm/components/FormCore/FormProvider.mjs
Attempted import error: 'useForm' is not exported from 'react-hook-form' (imported as 'useForm').
Import trace for requested module:
./node_modules/@aws-amplify/ui-react-core/dist/esm/components/FormCore/FormProvider.mjs
./node_modules/@aws-amplify/ui-react-core/dist/esm/index.mjs
./node_modules/@aws-amplify/ui-react/dist/esm/index.mjs
./app/layout.tsx
GET / 500 in 5217ms
Additional information and screenshots
package.json
{
"name": "dashboard-aws-app",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@aws-amplify/ui-react": "^6.1.9",
"@aws-amplify/ui-react-storage": "^3.1.0",
"aws-amplify": "^6.3.0",
"next": "14.2.3",
"react": "^18",
"react-dom": "^18",
"react-hook-form": "^7.51.4"
},
"devDependencies": {
"@types/node": "^20",
"@types/react": "^18",
"@types/react-dom": "^18",
"eslint": "^8",
"eslint-config-next": "14.2.3",
"postcss": "^8",
"tailwindcss": "^3.4.1",
"typescript": "^5"
}
}
tsconfig.json
{
"compilerOptions": {
"lib": ["dom", "dom.iterable", "esnext"],
"allowJs": true,
"skipLibCheck": true,
"strict": true,
"noEmit": true,
"esModuleInterop": true,
"module": "esnext",
"moduleResolution": "bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"jsx": "preserve",
"incremental": true,
"plugins": [
{
"name": "next"
}
],
"paths": {
"@/*": ["./*"]
}
},
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
"exclude": ["node_modules"]
}
Hey @varundhand 👋 I wasn't able to reproduce this error. Can you share some more information about your file structure?
I noticed you're calling withAuthenticator twice, but you'll only want to call that once in your main app component, in the same place you're calling Amplify.configure.
I also see react-hook-form listed as a dependency, is that being used for something unrelated to this issue? You shouldn't need to list it as a dep to use @aws-amplify/ui-react-storage and it might be causing conflicting dependencies.
Try deleting node_modules and running npm install again. If that doesn't work, look into node_modules to verify that the package versions installed are what you expect them to be, and we can debug further from there.
Hi @varundhand, I noticed you have wrapped the app inside withAuthenticator twice in the example. If you remove the one in layout.tsx and just keep the other one in page.tsx, I believe it will work for you. The error message there is confusing and does not reflect the root cause. The error was thrown because you were using the authenticator in a server component(layout.tsx in this case).
Hey @zchenwei, thanks for catching that! I removed the redundant withAuthenticator from the layout file and it did the trick. Thanks for the help!
Thanks to @esauerbo as well!