TypeError: Failed to parse URL from /api/recommendations/sAvdpLZ4kwN1
Answered
Chinese perch posted this in #help-forum
Chinese perchOP
I was getting this error on Nextjs 14 as well as on 15. I'm aware that this kind of error occurs when we fetch a relative URL in
Server Component
but I'm fetching this URL in a Client Component
.// src/app/rec/[id]/page.tsx
import { Recommendations } from '@/app/rec/Recommendations';
export default async function RecommendationsPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
return (
<div>
<Recommendations id={id} />
</div>
);
}
// src/app/rec/Recommendations.tsx
'use client';
import { useZustandStore } from '@/util/store';
import { TrackCard } from '../TrackCard';
export function Recommendations({ id }: { id: string }) {
const recommendedTracks = useZustandStore(state => state.recommendedTracks);
const setRecommendedTracks = useZustandStore(state => state.setRecommendedTracks);
const fetchStoredTracks = async () => {
const res = await fetch(`/api/recommendations/${id}`);
const data = await res.json();
if (data) {
setRecommendedTracks(data.tracks);
} else {
setRecommendedTracks(null);
}
};
if (recommendedTracks.length === 0) {
fetchStoredTracks();
}
return (
<div>
{recommendedTracks.map(track => {
return <TrackCard key={track.id} track={track} />;
})}
</div>
);
}
Answered by James4u (Tag me if needed)
one of followings should fix your problem
- wrap your fetch logic inside
- add
- use
- wrap your fetch logic inside
useEffect()
- add
client-only
to your page - use
next/dynamic
with ssr: false
14 Replies
one of followings should fix your problem
- wrap your fetch logic inside
- add
- use
- wrap your fetch logic inside
useEffect()
- add
client-only
to your page - use
next/dynamic
with ssr: false
Answer
@Chinese perch
note that client components are still rendered on the server
Chinese perchOP
@James4u (Tag me if needed) Thanks. I ended up using
useEffect
and it fixed the issue. However, I kind of don't like using this hook. Couldn't find any docs on client-only
and for the dynamic import I'm getting the following TS error:Argument of type '() => Promise<typeof import("e:/orpheus/src/app/rec/Recommendations")>' is not assignable to parameter of type 'DynamicOptions<{}> | Loader<{}>'.
Type '() => Promise<typeof import("e:/orpheus/src/app/rec/Recommendations")>' is not assignable to type '() => LoaderComponent<{}>'.
Type 'Promise<typeof import("e:/orpheus/src/app/rec/Recommendations")>' is not assignable to type 'LoaderComponent<{}>'.
Type 'typeof import("e:/orpheus/src/app/rec/Recommendations")' is not assignable to type 'ComponentType<{}> | ComponentModule<{}>'
Also, what's the point of having
'use client'
if it ends up being executed on server?well,
client-only
is a different thing from dynamic importnext/dynamic
with ssr: false
⬆️use client
indicates the root of the client boundry - you can use hooks, event handlers in your client component - you can think it as "use interactive"it doesn't mean it's rendered only on the client end
Chinese perchOP
yes, I got that part 2 & 3 are different solutions, I'm just saying the dynamic import is giving me a TS error. And I can't find anything about 'client-only' on googling
show me how you tried to do lazy loading with
next/dynamic
Chinese perchOP
@James4u (Tag me if needed) here
import dynamic from 'next/dynamic';
const Recommendations = dynamic(() => import('@/components/Recommendations'), { ssr: false });
export default async function RecommendationsPage({ params }: { params: Promise<{ id: string }> }) {
const { id } = await params;
return (
<div>
<Recommendations id={id} />
</div>
);
}