From abb9ffa1a66e0e33c1a4526abaa067db4124fedf Mon Sep 17 00:00:00 2001 From: FliesentischKing Date: Sat, 17 Oct 2026 17:47:28 +0200 Subject: [PATCH] Persist viewport dimensions in a cookie so SSR renders full-height grid skeletons Generated with [Devin](https://devin.ai) Co-Authored-By: Devin <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- app/composables/usePageSize.ts | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/app/composables/usePageSize.ts b/app/composables/usePageSize.ts index f49858c..228df70 100644 --- a/app/composables/usePageSize.ts +++ b/app/composables/usePageSize.ts @@ -5,6 +5,8 @@ import { useWindowSize } from '@vueuse/core' // grid-cols-4 sm:6 md:8 lg:12, auto-rows 6.5rem / sm:7rem / lg:7.5rem, gap-2 const PAGINATION_RESERVE_PX = 60 // Pagination (~36px) + pt-4, knapp bemessen damit die letzte Zeile nicht wegfällt const FALLBACK_TOP_PX = 150 // SSR-Schätzung: Header + Padding + Filterzeile +const DEFAULT_SSR_WIDTH = 1920 +const DEFAULT_SSR_HEIGHT = 1080 interface PageSizeOptions { // [base, sm (>=640px), lg (>=1024px)] — Zeilenhöhe in rem ohne Grid-Gap @@ -15,10 +17,26 @@ interface PageSizeOptions { export function usePageSize(anchor: Ref, options: PageSizeOptions = {}) { const { rowHeights = [6.5, 7, 7.5], gapBelowAnchorPx = 8 } = options - const { width, height } = useWindowSize() + const savedVp = useCookie<{ w: number, h: number }>('vp-size', { + default: () => ({ w: DEFAULT_SSR_WIDTH, h: DEFAULT_SSR_HEIGHT }), + sameSite: 'lax', + }) + const { width, height } = useWindowSize({ + initialWidth: savedVp.value?.w || DEFAULT_SSR_WIDTH, + initialHeight: savedVp.value?.h || DEFAULT_SSR_HEIGHT, + }) + if (import.meta.client) { + watch([width, height], ([w, h]) => { + if (Number.isFinite(w) && Number.isFinite(h) && w > 0 && h > 0) { + if (savedVp.value?.w !== w || savedVp.value?.h !== h) { + savedVp.value = { w, h } + } + } + }, { immediate: true }) + } const cols = computed(() => { - const w = Number.isFinite(width.value) ? width.value : 1280 + const w = Number.isFinite(width.value) ? width.value : (savedVp.value?.w || DEFAULT_SSR_WIDTH) return w >= 1024 ? 12 : w >= 768 ? 8 : w >= 640 ? 6 : 4 }) @@ -59,8 +77,8 @@ export function usePageSize(anchor: Ref, options watch([width, height], measureAnchor, { flush: 'post' }) const cells = computed(() => { - const w = Number.isFinite(width.value) ? width.value : 1280 - const h = Number.isFinite(height.value) ? height.value : 800 + const w = Number.isFinite(width.value) ? width.value : (savedVp.value?.w || DEFAULT_SSR_WIDTH) + const h = Number.isFinite(height.value) ? height.value : (savedVp.value?.h || DEFAULT_SSR_HEIGHT) const rem = import.meta.client ? Number.parseFloat(getComputedStyle(document.documentElement).fontSize) || 16 : 16