Fetching data directly from client component (Without using Route Handlers or SWR)
Answered
American Crocodile posted this in #help-forum
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
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();
}, []);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:
Then you can query the api with the following syntax to get the ip of the said ip:
"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.
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.
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.
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
@James4u one thing <@217798247626833922> can you try that in incognitor mode?
tried? @American Crocodile ?
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!