da294010c8
- Changed site URLs in docker-compose and deployment configurations to remove "www" prefix for consistency. - Improved image handling by introducing warmPostCardImages function for pre-fetching images in posts and tags. - Enhanced PostCard component with responsive image sizes for better performance. - Updated layout to include robots meta tag and JSON-LD structured data for improved SEO. - Added loading state for images in TopBanner component to enhance user experience.
117 lines
3.8 KiB
TypeScript
117 lines
3.8 KiB
TypeScript
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,
|
|
} from '$lib/blog-utils';
|
|
import { DEFAULT_HOME_PAGE_SLUG, PAGE_RESOLVE, SITE_NAME } from '$lib/constants';
|
|
|
|
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 {
|
|
// fallback
|
|
}
|
|
|
|
let page = null;
|
|
let pages: Awaited<ReturnType<typeof getPages>> = [];
|
|
|
|
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);
|
|
}
|
|
} catch {
|
|
// CMS nicht erreichbar
|
|
}
|
|
|
|
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,
|
|
};
|
|
};
|