reactjsnext.jsrouternext.js13app-router

useRouter only works when I reach my website's error page (NextJS)


Whenever a query is submitted in my search bar component, the current webpage doesn't actually change, with only a /? showing up at the end of the website's URL. However, when I manually type in an incorrect page route into the router (for example, /test), the search bar suddenly works as intended whenever I submit a query with it by pushing the query to the end of the URL path. Reloading the web page reintroduces the problem. For the component to be working correctly, it should be pushing /search?q=[QUERY HERE] to the router.

What's going on? Is this a bug with NextJS or am I doing something incorrectly? For context, I'm using the App Router and this component is a layout component.

search-bar.tsx:

"use client";
import { useState } from "react";
import styles from "../app/styles/navbar.module.css"
import { useRouter, useSearchParams } from "next/navigation";

const SearchBar: React.FC = () => {
    const [query, setQuery] = useState("");
    const searchParams = useSearchParams();
    let router = useRouter();

    return (
        <form className={ styles.search } onSubmit={() => router.replace("/search?q=" + query)}>
            <input type="text" placeholder="Search here..." value={ query } onChange={(e) => setQuery(e.target.value)}/>
            <button type="submit" onClick={() => router.replace("/search?q=" + query)}>Search</button>
        </form>
    );
}

export default SearchBar;

Solution

  • Tried using redirect instead of useRouter and now it works. Copied the client component example from the docs: https://nextjs.org/docs/app/api-reference/functions/redirect

    search-bar.tsx

    "use client";
    import { useState } from "react";
    import styles from "../app/styles/navbar.module.css"
    import Navigate from "./redirect";
    
    const SearchBar: React.FC = () => {
        const [query, setQuery] = useState("");
    
        return (
            <form className={ styles.search } action={Navigate}>
              <input type="text" placeholder="Search here..." name="query" value={ query } onChange={(e) => setQuery(e.target.value)}/>
                <button type="submit">Search</button>
            </form>
        )
    }
    
    export default SearchBar;
    

    redirect.tsx

    "use server"
     import { redirect } from 'next/navigation';
    
    const Navigate: React.FC<FormData> = async (data: FormData) => {
        redirect(`/search/?q=${data.get('query')}`)
    }
    
    export default Navigate;