1

I have a very basic project structure with just a root route. In my page.tsx, which is a server component, I fetch and show a list of countries from REST countries API endpoint.

I also have a client component search-bar.tsx which has a search input to search and filter for countries, the results of which will be shown inside of page.tsx

My problem is once I search for a country for which the API returns a 404 and my error.tsx error boundary component UI is rightly triggered, I am not able to re-render the server component inside page.tsx back from error.tsx. I have used all variations like router.push("/") , revalidatePath() and router.refresh()

Code files below:

pages.tsx

import Navbar from "./navbar";
import SearchBar from "./search-bar";
import Select from "./select";
import Countries from "./countries";

const getCountriesData = async () => {
  const res = await fetch("https://restcountries.com/v3.1/all", {
    cache: "no-store"
  });
  if (!res.ok) {
    throw new Error("Failed to fetch all data");
  }
  return res.json();
};

const getCountryByName = async (countryName: string) => {
  const res = await fetch(`https://restcountries.com/v3.1/name/${countryName}`);
  if (!res.ok) {
    throw new Error("Failed to fetch country data");
  }
  return res.json();
}

export default async function Home({params, searchParams}: {params: Params, searchParams: SearchParams}) {
  const countries: Array<any> = searchParams.search ?  await getCountryByName(searchParams.search as string) : await getCountriesData()
  return (
    <main className="flex flex-col gap-2 overflow-x-hidden">
      <header>
        <Navbar />
      </header>
      <div className="flex justify-between p-2 md:p-4">
        <SearchBar />
        <Select />
      </div>
      <div className="flex flex-wrap justify-between gap-4 p-2 md:p-4">
        <Countries countries={countries} />
      </div>
    </main>
  );
}

search-bar.tsx

"use client";

import { useRouter } from "next/navigation";
import { ChangeEvent, useEffect, useMemo, useState } from "react";

const SearchBar = () => {
  const [searchTerm, setSearchTerm] = useState("");
  const router = useRouter();

  const debounce = <F extends (...args: Parameters<F>) => ReturnType<F>> (fn: F, delay: number) => {
    let timer: ReturnType<typeof setTimeout>
    return (...args: Parameters<F>) => {
      clearTimeout(timer);
      timer = setTimeout(() => fn(...args), delay);
    }
  }

  const handleSearch = (e: ChangeEvent<HTMLInputElement>) => {
    setSearchTerm(e.target.value);
    router.push(`/?search=${e.target.value}`)
  };

  const debouncedSearch = debounce(handleSearch, 500)

  return (
    <div className="flex gap-1 items-center">
      <img
        src="/search-magnifying-glass-svgrepo-com.svg"
        alt="search icon"
        width={20}
        height={20}
      />
      <input
        type="text"
        name="search-country"
        placeholder="Search for a country..."
        className="url"
        onChange={(e) => debouncedSearch(e)}
      />
    </div>
  );
};

export default SearchBar;

error.tsx

"use client";

import { revalidatePath } from "next/cache";
import Link from "next/link";
import { redirect, useRouter } from "next/navigation";
import { useEffect } from "react";

const Error = ({error, reset}: {error: Error, reset: () => void}) => {
    console.log(error);
    const router = useRouter();

    reset = () => {
      router.push("/");
      router.refresh();
    }

    useEffect(() => {
        console.error(error);
    }, [error])
    return (
        <div>
        <h2 className="text-red-400">Something went wrong!</h2>
        <button
          onClick={
            // Attempt to recover by trying to re-render the segment
            () => reset()
          }
        >Here
        </button>
        {/* <Link href="/">Click here to go back</Link> */}
      </div>
    )
}

export default Error;

Please note I am able to reset the path back to "/" aka root route from error.tsx and an API call is fired to get all countries but the component or UI in page.tsx is not rendered and I keep seeing the error boundary UI

Any help is appreciated!

0 Answers0