javascriptreactjshttp-redirectremix.run

How to redirect to another page in Remix.run?


I was trying to redirect to another page in Remix.run

// app/routes/signup.jsx
import { redirect } from "@remix-run/node";

export default function Signup() {
  return (
    <>
      <h1>Signup to SolveIt</h1>
      <button onClick={() => redirect("/login")}>Login</button> // trying to redirect to '/login' route
    </>
  );
}

But, I'm getting an error in the console everytime which says :

Uncaught TypeError: (0 , import_node.redirect) is not a function

Solution

  • In Remix, redirects are performed on the server inside a loader or action.

    Your example looks like it could be handled by a simple <Link>

    export default function Signup() {
      return (
        <>
          <h1>Signup to SolveIt</h1>
          <Link to="/logon">Login</Link>
        </>
      );
    }
    

    Here is how you would do it if you really needed to redirect

    // routes/login.tsx
    
    export async function action({ request }: ActionArgs) {
      const formData = await request.formData()
      const username = formData.get("username")
      const password = formData.get("password")
    
      const isValid = await validateUser(username, password)
    
      if (isValid) {
        throw redirect('/') // valid login so redirect to home page
      }
      return json({ formError: 'Invalid username or password' })
    }
    
    export default function Login() {
      const data = useActionData<typeof action>()
      return (
        <Form method="post">
          <input type="text" name="username" placeholder="Enter username" />
          <input type="password" name="password" placeholder="Enter password" />
          <button>Login</button>
          { data?.formError && <p>{data?.formError}</p> }
        </Form>
      )
    }
    

    Here we post the username and password to the action function. We get the form data from the request. We can then verify if the credentials are valid. If so, we throw redirect('/'). The redirect function returns a Response with the correct status and headers.

    If it is invalid, we return an error message to the user with the json function. Note how we used throw instead of return for the redirect. This is so we can use type inference in the call to useActionData<typeof action>(). Remix will infer the return value from the payload of json and defer functions.

    In the UI component, we check for the error with useActionData(). Since it only returns a value after an action call (POST), it can also be undefined. We check if data?.formError has a value and if so render it.