How to render conditional api string depending on screen size?
Answered
Dutch posted this in #help-forum
DutchOP
Im trying to conditionally render a limit for my api depending on the screen size in a server component, atm im getting error "window is not defined" can someone help?
here's my code:
thank you!
here's my code:
import MovieCardList from '@/components/MovieCardList';
import PaginationControls from '@/components/PaginationControls';
import MovieSearchBar from '@/components/MovieSearchBar';
import { getFilterdMovie } from '@/utils/api';
import MovieDynamicHeading from '@/components/MovieDynamicHeading';
import { Suspense } from 'react';
import Loader from '@/components/Loader';
export default async function MoviePage({ searchParams }) {
const defaultLimit = 10;
const calculateLimit = () => {
const windowWidth = window.innerWidth;
if (windowWidth >= 3248) return 20;
if (windowWidth > 2923) return 20;
if (windowWidth <= 2923 && windowWidth > 2599) return 24;
if (windowWidth <= 2599 && windowWidth > 2275) return 21;
if (windowWidth <= 2275 && windowWidth > 1951) return 24;
if (windowWidth <= 1951 && windowWidth > 1627) return 25;
if (windowWidth <= 1627 && windowWidth > 1303) return 24;
return defaultLimit;
};
const limit = calculateLimit();
const { page = '1', order = 'members', status = 'all', search = '', type = 'all', genres = '' } = searchParams;
const orderParam = `order_by=${order}`;
const sortParam = '&sort=desc';
const limitParam = `&limit=${limit}`;
const statusParam = status && status !== 'all' ? `&status=${status}` : '';
const pageParam = `&page=${page}`;
const searchParam = search ? `&q=${search}` : '';
const typeParam = type !== 'all' ? `&type=${type}` : '';
const genreParam = genres ? `&genres=${genres}` : '';
const params = `${orderParam}${sortParam}${limitParam}${statusParam}${pageParam}${searchParam}${typeParam}${genreParam}&sfw`;
const data = await getFilterdMovie(params);
return (
<div className='px-4 pt-32'>
<MovieDynamicHeading data={data} order={order} status={status} search={search} type={type} genres={genres} />
<Suspense fallback={<Loader />}>
<MovieSearchBar order={order} status={status} search={search} type={type} genres={genres} />
</Suspense>
<MovieCardList data={data?.data} limit={limit} />
<Suspense fallback={<Loader />}>
<PaginationControls pagination={data?.pagination} />
</Suspense>
</div>
);
}thank you!
Answered by Ray
It is because the page will be rendered on the server and
Could you try to do the calculation in a useEffect?
window is not available.Could you try to do the calculation in a useEffect?
12 Replies
@Ray It is because the page will be rendered on the server and `window` is not available.
Could you try to do the calculation in a useEffect?
DutchOP
So i should make the whole page.js file 'use client'; ?
or try this
const calculateLimit = () => {
if (typeof window === "undefined") return defaultLimit;
const windowWidth = window.innerWidth;
if (windowWidth >= 3248) return 20;
if (windowWidth > 2923) return 20;
if (windowWidth <= 2923 && windowWidth > 2599) return 24;
if (windowWidth <= 2599 && windowWidth > 2275) return 21;
if (windowWidth <= 2275 && windowWidth > 1951) return 24;
if (windowWidth <= 1951 && windowWidth > 1627) return 25;
if (windowWidth <= 1627 && windowWidth > 1303) return 24;
return defaultLimit;
};@Dutch So i should make the whole page.js file 'use client'; ?
For your case, I think this should work
ah but might get hydration error
@Ray For your case, I think this should work
DutchOP
was hoping to find a way to avoid it as im using await for fetching and stuff
i appreciate the help tho
@Dutch this doesnt work, it always returns defaultLimit
you would need useEffect with this then
DutchOP
ðŸ‘
it's impossible to know the screen width on the server
just fetch the same number of items for all viewports, then use css/client side js to determine how many items are displayed based on screen size