import type { PageServerLoad } from './$types'; import { getPageBySlug, getPages, getHomePageSlugFromConfig } from '$lib/cms'; import { extractCmsImageField, resolveContentImages, resolveImageUrls, } from '$lib/rusty-image'; import { buildResponsiveImage, warmResponsiveImage, type ResponsiveImage } from '$lib/rusty-image.server'; import { resolvePostOverviewBlocks, resolveSearchableTextBlocks, resolveCalendarBlocks, resolveDeadlineBannerBlocks, } from '$lib/blog-utils'; import { DEFAULT_HOME_PAGE_SLUG, PAGE_RESOLVE, SITE_NAME } from '$lib/constants'; import { sanitizeBlocks } from '$lib/sanitize-blocks.server'; import { logWarn } from '$lib/log.server'; const BANNER_WIDTHS = [640, 960, 1280, 1600, 1920]; const BANNER_AR = '16/9'; function focalToCss(focal: { x: number; y: number } | undefined): string | null { if (!focal) return null; return `${(focal.x * 100).toFixed(2)}% ${(focal.y * 100).toFixed(2)}%`; } export const load: PageServerLoad = async ({ locals, fetch }) => { const translations = locals.translations ?? {}; let homeSlug = DEFAULT_HOME_PAGE_SLUG; try { homeSlug = (await getHomePageSlugFromConfig({ locale: 'de' })) ?? DEFAULT_HOME_PAGE_SLUG; } catch (err) { logWarn('home.slug', err); } let page = null; let pages: Awaited> = []; try { const [homePage, allPages] = await Promise.all([ getPageBySlug(homeSlug, { locale: 'de', resolve: PAGE_RESOLVE }), getPages(), ]); page = homePage; pages = allPages ?? []; if (page) { await resolveContentImages(page); const tagsMap = await resolvePostOverviewBlocks(page); await resolveSearchableTextBlocks(page, tagsMap); await resolveCalendarBlocks(page); await resolveDeadlineBannerBlocks(page); sanitizeBlocks(page); } } catch (err) { logWarn('home.page', err, { homeSlug }); } const siteName = (import.meta.env.PUBLIC_SITE_NAME as string | undefined) || SITE_NAME; let topBanner: { banner: import('$lib/cms').FullwidthBannerEntry | null; resolvedImages: string[]; responsive: ResponsiveImage | null; focalCss: string | null; headline?: string; subheadline?: string; } | null = null; if (page) { const bannerRaw = (page as { topFullwidthBanner?: unknown }).topFullwidthBanner; if (bannerRaw && typeof bannerRaw === 'object' && 'image' in bannerRaw) { const bannerImages = Array.isArray((bannerRaw as { image?: unknown }).image) ? ((bannerRaw as { image?: unknown[] }).image ?? []) : (bannerRaw as { image?: unknown }).image != null ? [(bannerRaw as { image?: unknown }).image] : []; let resolvedImages: string[] = []; let responsive: ResponsiveImage | null = null; let focalCss: string | null = null; if (bannerImages.length > 0) { const primary = extractCmsImageField(bannerImages[0]); if (primary?.url) { focalCss = focalToCss(primary.focal); responsive = await buildResponsiveImage(primary.url, { widths: BANNER_WIDTHS, fit: 'cover', ar: BANNER_AR, quality: 72, focal: primary.focal, }); } resolvedImages = await resolveImageUrls(bannerImages as string[], { width: 2000, height: 750, fit: 'cover', format: 'webp', }); } warmResponsiveImage(responsive, fetch); topBanner = { banner: bannerRaw as import('$lib/cms').FullwidthBannerEntry | null, resolvedImages, responsive, focalCss, headline: page.headline ?? undefined, subheadline: page.subheadline ?? undefined, }; } } return { page, pages, translations, topBanner, seoTitle: page ? (page.seoTitle ?? page.headline ?? page.linkName ?? siteName) : siteName, seoDescription: page ? (page.seoDescription ?? page.subheadline ?? '') : '', robots: (page as { seoMetaRobots?: string } | null)?.seoMetaRobots ?? undefined, keywords: (page as { seoKeywords?: string } | null)?.seoKeywords ?? undefined, }; };