1

I have just started working on nextJS 13.4.12 and currently shifting a project from react to nextJS. While working on the login page I found that nextJS does not allow to use react-hook-form or @hookform/resolvers/yup on server-side components. For them to work you need to add use client at the very top of the component. And I also did that.

But to my surprise when I see the network request I can still see the basic HTML code consisting of input, buttons, and some other tags as well. How does ssr happening here?

PS: I have seen a ton of articles, tutorials, snippets, and docs. They were directly using hook-form, yupresolver without actually specifying use client. Although they were mostly using 13.0.5. enter image description here

Here is my code

// React Imports
'use client';
import Link from 'next/link';
import { useForm, Controller } from 'react-hook-form';
import './login.css';
import Image from 'next/image';
// Resolvers & Schema
import { yupResolver } from '@hookform/resolvers/yup';
import { signupSchema } from '@/schema/auth';
// Others
import { headerNameLogo } from '@/EntryFile/imagePath';
import Head from 'next/head';

export default function Login() {
    const {
        handleSubmit,
        control,
        setError,
        clearErrors,
        formState: { errors, isValid },
    } = useForm({
        mode: 'onChange',
        resolver: yupResolver(signupSchema),
    });

    return (
        <>
            <Head>
                <title>Login - HRXpress</title>
                <meta name="description" content="Login page" />
                <script src="./togglePassword.ts"></script>
            </Head>
            <div className="account-content">
                <div className="container">
                    {/* Account Logo */}
                    <div className="account-logo" style={{ marginTop: 70 }}>
                        <Link href="/app/main/dashboard">
                            <Image
                                style={{ width: 'auto', mixBlendMode: 'darken' }}
                                src={headerNameLogo}
                                alt="HRXpress"
                            />
                        </Link>
                    </div>
                    {/* /Account Logo */}
                    <div className="account-box">
                        <div className="account-wrapper">
                            <h3 className="account-title">Login</h3>
                            <p className="account-subtitle">Access to our dashboard</p>
                            {/* Account Form */}
                            <div>
                                <form
                                    onSubmit={(e) => {
                                        e.preventDefault();
                                    }}
                                >
                                    <div className="form-group">
                                        <label>Email Address</label>
                                        <Controller
                                            name="email"
                                            control={control}
                                            render={({ field: { value, onChange } }) => (
                                                <input
                                                    className={`form-control  ${
                                                        errors?.email ? 'error-input' : ''
                                                    }`}
                                                    type="text"
                                                    value={value}
                                                    onChange={onChange}
                                                    autoComplete="false"
                                                />
                                            )}
                                            defaultValue="admin@dreamguys.co.in"
                                        />
                                        <small>{errors?.email?.message}</small>
                                    </div>
                                    <div className="form-group">
                                        <div className="row">
                                            <div className="col">
                                                <label>Password</label>
                                            </div>
                                            <div className="col-auto">
                                                <Link className="text-muted" href="/forgotpassword">
                                                    Forgot password?
                                                </Link>
                                            </div>
                                        </div>
                                        <Controller
                                            name="password"
                                            control={control}
                                            render={({ field: { value, onChange } }) => (
                                                <div className="pass-group">
                                                    <input
                                                        type="password"
                                                        className={`form-control  ${
                                                            errors?.password ? 'error-input' : ''
                                                        }`}
                                                        value={value}
                                                        onChange={onChange}
                                                        autoComplete="false"
                                                    />
                                                    <span
                                                        id="togglePassword"
                                                        className="fa toggle-password fa-eye"
                                                    />
                                                </div>
                                            )}
                                            defaultValue="123456"
                                        />
                                        <small>{errors?.password?.message}</small>
                                    </div>
                                    <div className="form-group text-center">
                                        <button
                                            disabled={!isValid}
                                            className="btn btn-primary account-btn"
                                            type="submit"
                                        >
                                            Login
                                        </button>
                                    </div>
                                </form>
                                <div className="account-footer">
                                    <p>
                                        Don't have an account yet?{' '}
                                        <Link href="/register">Register</Link>
                                    </p>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </>
    );
}
Joy Gupta
  • 122
  • 6

1 Answers1

1

It is because in latest version of nextJS each component is firstly rendered on the server side, irrespective of directive you've used. Please refer here for more.

Amit
  • 26
  • 2