Next.js Discord

Discord Forum

Fetching data directly from client component (Without using Route Handlers or SWR)

Answered
American Crocodile posted this in #help-forum
Open in Discord
American CrocodileOP
Hello, I have the following problem.

I want to determine the country of my current user by fetching data from https://api.country.is/. This API will return the user's IP and country information.

However, I want to perform this fetch on the client side. If I use it in a client component with route handlers, I would get the IP and country of the server, not the user.

Is it possible to fetch directly within the useEffect hook, as in a standard React setup?


This is my code

  useEffect(() => {
    async function fetchCountry() {
      try {
        const res = await fetch("https://api.country.is/");
        if (!res.ok) {
          throw new Error(
            `Failed to fetch user country: ${res.status} ${res.statusText}`,
          );
        }
        const data = await res.json();
        console.log(data);
      } catch (error) {
        console.error("Error fetching user country:", error);
      }
    }

    fetchCountry();
  }, []);
Answered by James4u
it can! if you have extensions like adblocker
View full answer

27 Replies

I guess there is a package client-only just like server-only. Give that a try. .
Sun bear
You can get the ip of the user on server with the following server action:

"use server"
import { headers } from "next/headers"
import { NextRequest } from "next/server"

export async function getUserIp() {
    const headersList = headers();
    const ip = headersList.get("x-forwarded-for");

    return NextResponse.json({ip})
}


Then you can query the api with the following syntax to get the ip of the said ip:

const { ip } = await getUserIp()
const res = await fetch(`https://api.country.is/${ip}`)
in short you can get the user ip using a server action then append the ip to the end of the url to get the ip of a said country.
yeah, why not? you can! @American Crocodile
@James4u yeah, why not? you can! <@217798247626833922>
American CrocodileOP
Whenever I try the code in the snippet I get fetch error.
Try it yourself inside a client component.
American CrocodileOP
@James4u
bascially the response was not "ok"

it's the error message I prepared myself when an error occured.
@James4u nope, it can't be. https://api.country.is/ try this link in your browser
American CrocodileOP
yes it works just fine, but fetching it inside a useEffect won't work, did you try it yourself?

it will work if I used route handler. but then I would get the country of the server and not the user.
Sun bear
wait is the getUserIp problem or the fetch?
one thing @American Crocodile can you try that in incognitor mode?
@Sun bear wait is the `getUserIp` problem or the fetch?
American CrocodileOP
my problem is the fetch, it won't allow me to fetch in a client component if it's not a route-handler
American CrocodileOP
Won't make a difference, but I try in a second.
it can! if you have extensions like adblocker
Answer
Sun bear
maybe use the fetch inside the server action aswell
@James4u it can! if you have extensions like adblocker
American CrocodileOP
my lord! it was the ad blocker, i'm going to commit a seppuku
Sun bear
:D
ofc. I actually tried on codesandbox and get an error - but wanted give you a chance to find it by yourself 🙂
American CrocodileOP
thank you very much for the help
my pleasure, just mark as solution so that others can turn their adblockers off for sure
haha but I think it's better to handle that in the server side
because most of users will have adblocker on their browser
@James4u haha but I think it's better to handle that in the server side
American CrocodileOP
yeah, but it will require a lot of gymnastics, and if a user don't want me to have his ip it's ok. no big deal.
thanks you very much dude again, have a great day!
you too!