function is running in browser context instead of server
Unanswered
American Chinchilla posted this in #help-forum
American ChinchillaOP
so i have this function
export async function getChannels(guildId: string): Promise<any> {
console.log(process.env.TOKEN, "TOKEN")
const res = await fetch(
`https://discord.com/api/guilds/${guildId}/channels`,
{
headers: {
authorization: `Bot ${process.env.TOKEN}`,
},
}
)
if (!res.ok) {
throw new Error(`Failed to fetch channels (Code: ${res.status})`)
}
return await res.json()
} and im logging out the TOKEN but it is logged out on the server side as well as on the client side but it says undefined TOKEN and its causing errors when it run on browser how to make it not this is how im calling thisimport { getChannels } from "@/lib/utils"
export default async function ChannelSelect({ guildId }: { guildId: string }) {
const channels = await getChannels(guildId)
return (
<div>
<p>ChannelSelect</p>
</div>
)
} and this component is inside another component that has use client37 Replies
Prefix the name of the env variable with
NEXT_PUBLIC_So it will become
NEXT_PUBLIC_TOKENAmerican ChinchillaOP
but i dont want it on client side
but it does run there
Without nextpublic it shouldn't be available on the client tho
Giant panda
Anything beyond the
use client boundary becomes a client component by design@Clown Without next_public_ it shouldn't be available on the client tho
Giant panda
This isn't the problem
@Clown Without next_public_ it shouldn't be available on the client tho
American ChinchillaOP
hence its undefined i know but it shouldnt even be logged in browser
Giant panda
If you want to have a server component be a child of a client component you must pass it into it via props such as children
<ClientComponent>
<ServerComponent />
</ClientComponent>or
<ClientComponent somethingComponent={<ServerComponent />} />In your case
ChannelSelect being the server componentAmerican ChinchillaOP
so i cant just do
"use client"
import ChannelSelect from "./ChannelSelect"
export default function FormComponent() {
return (<div>
<ChannelSelect />
</div>)Giant panda
No
Because everything beyond the
use client directive is a client components as I've mentioned beforeSo you'd have to pass server components from the outside via props to your FormComponent
American ChinchillaOP
i dont really see how i should implement the children passing
American ChinchillaOP
alright ill try this
American ChinchillaOP
yea now im getting this
Access to fetch at 'https://discord.com/api/guilds/1061263631511191632/channels' from origin 'http://localhost:3000' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled. :/Giant panda
Then you didn't do it correctly. Read the docs I linked for examples.
American ChinchillaOP
ok thanks
@Giant panda Then you didn't do it correctly. Read the docs I linked for examples.
American ChinchillaOP
problem comes when i have to get the value from context to make that api call
cause basically when im at
and now when im creating a subpage like
/dashboard/{guildId} the current guild object is held in context so i dont have to fetch it each time i need it based on id in urland now when im creating a subpage like
/dashboard/{guildId}/welcome and i wanted to create a form there that has a select with each channel that this guild has and i have to make an discord api call there based on guild id i have in contextwhat do you suggest to do for that case?
Giant panda
Your initial code above does not indicate any of that.
American ChinchillaOP
sorry i didnt want to overcomplicate it this much so i didnt include those details
Giant panda
If you need to fetch based on data on the client-side you either have to fetch client-side or share the data with a server component using the URL
American ChinchillaOP
yea i need value that is on client to make api call on the server to get this info to client to display channels
@Giant panda If you need to fetch based on data on the client-side you either have to fetch client-side or share the data with a server component using the URL
American ChinchillaOP
i cant fetch client side cause the authorization token is a secret
Giant panda
You can proxy the request through a route handler if you want to fetch client-side
American ChinchillaOP
how would that work
Giant panda
You do the data fetching in a route handler and keep the secret server-side
And call your own route handler from client-side
American ChinchillaOP
ah so like an api endpoint
and i get the guild id as param and return json to client
American ChinchillaOP
hey @Giant panda
so i did it like this i have a file at
so i did it like this i have a file at
app/api/guild/channels/[guildId]/route.ts and then how would i fetch it? i tried this const res = await fetch(`/api/guild/channels/${params.guildId}`)
const channels = await res.json() but i get Error: Failed to parse URL from /api/guild/channels/1061263631511191632