Før aleggsbilde-interface
This commit is contained in:
parent
8bfd351582
commit
5a1944b216
2 changed files with 78 additions and 9 deletions
|
|
@ -1,5 +1,6 @@
|
|||
import { ImageResponse } from "next/og";
|
||||
import { API_URL } from "@/config/constants";
|
||||
import { resolveFacilityAlias } from "@/app/facilityAliases";
|
||||
import { buildAbsoluteUrl } from "@/app/seo";
|
||||
|
||||
export const size = {
|
||||
|
|
@ -13,14 +14,44 @@ type OpenGraphImageProps = {
|
|||
params: Promise<{ slug: string }>;
|
||||
};
|
||||
|
||||
type OpenGraphFacility = {
|
||||
name: string;
|
||||
city?: string | null;
|
||||
county?: string | null;
|
||||
image_url?: string | null;
|
||||
};
|
||||
|
||||
async function getFacility(slug: string) {
|
||||
const res = await fetch(`${API_URL}/facilities/${slug}`, { cache: "no-store" });
|
||||
return res.json();
|
||||
if (!res.ok) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const facility = (await res.json()) as Partial<OpenGraphFacility> | null;
|
||||
if (!facility?.name) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return facility as OpenGraphFacility;
|
||||
}
|
||||
|
||||
async function getFacilityForSlug(slug: string) {
|
||||
const facility = await getFacility(slug);
|
||||
if (facility) {
|
||||
return facility;
|
||||
}
|
||||
|
||||
const canonicalSlug = await resolveFacilityAlias(slug);
|
||||
if (!canonicalSlug || canonicalSlug === slug) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return getFacility(canonicalSlug);
|
||||
}
|
||||
|
||||
export default async function OpenGraphImage({ params }: OpenGraphImageProps) {
|
||||
const { slug } = await params;
|
||||
const facility = await getFacility(slug);
|
||||
const facility = await getFacilityForSlug(slug);
|
||||
|
||||
const title = facility?.name || "TeeOff";
|
||||
const location = [facility?.city, facility?.county].filter(Boolean).join(" · ") || "Norske golfbaner";
|
||||
|
|
|
|||
|
|
@ -1,5 +1,8 @@
|
|||
import type { Metadata } from "next";
|
||||
import { notFound, permanentRedirect } from "next/navigation";
|
||||
import { API_URL } from "@/config/constants";
|
||||
import { resolveFacilityAlias } from "@/app/facilityAliases";
|
||||
import type { FacilityRecord } from "@/app/facilityData";
|
||||
import {
|
||||
createBreadcrumbJsonLd,
|
||||
createFacilityJsonLd,
|
||||
|
|
@ -13,17 +16,47 @@ type GolfCoursePageProps = {
|
|||
params: Promise<{ slug: string }>;
|
||||
};
|
||||
|
||||
type FacilityPageData = FacilityRecord & {
|
||||
address?: string | null;
|
||||
[key: string]: unknown;
|
||||
};
|
||||
|
||||
async function getFacility(slug: string) {
|
||||
const res = await fetch(`${API_URL}/facilities/${slug}`, { cache: "no-store" });
|
||||
return res.json();
|
||||
if (!res.ok) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const facility = (await res.json()) as Partial<FacilityPageData> | null;
|
||||
if (typeof facility?.id !== "number" || !facility?.name || !facility?.slug) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return facility as FacilityPageData;
|
||||
}
|
||||
|
||||
async function getCanonicalSlug(slug: string) {
|
||||
const canonicalSlug = await resolveFacilityAlias(slug);
|
||||
if (!canonicalSlug || canonicalSlug === slug) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return canonicalSlug;
|
||||
}
|
||||
|
||||
export async function generateMetadata({ params }: GolfCoursePageProps): Promise<Metadata> {
|
||||
const { slug } = await params;
|
||||
|
||||
try {
|
||||
const facility = await getFacility(slug);
|
||||
if (!facility || facility.error) {
|
||||
let facility = await getFacility(slug);
|
||||
if (!facility) {
|
||||
const canonicalSlug = await getCanonicalSlug(slug);
|
||||
if (canonicalSlug) {
|
||||
facility = await getFacility(canonicalSlug);
|
||||
}
|
||||
}
|
||||
|
||||
if (!facility) {
|
||||
return createPageMetadata({
|
||||
title: "Golfbane ikke funnet",
|
||||
description: "Golfbanen du prøvde å åpne finnes ikke på TeeOff.",
|
||||
|
|
@ -37,8 +70,8 @@ export async function generateMetadata({ params }: GolfCoursePageProps): Promise
|
|||
return createPageMetadata({
|
||||
title,
|
||||
description: trimDescription(facility.description) || fallbackDescription,
|
||||
path: `/golfbaner/${slug}`,
|
||||
image: `/golfbaner/${slug}/opengraph-image`,
|
||||
path: `/golfbaner/${facility.slug}`,
|
||||
image: `/golfbaner/${facility.slug}/opengraph-image`,
|
||||
});
|
||||
} catch {
|
||||
return createPageMetadata({
|
||||
|
|
@ -53,8 +86,13 @@ export default async function GolfCoursePage({ params }: GolfCoursePageProps) {
|
|||
const { slug } = await params;
|
||||
const facility = await getFacility(slug);
|
||||
|
||||
if (!facility || facility.error) {
|
||||
return <div className="p-20 text-center font-bold text-2xl">Fant ikke golfbanen...</div>;
|
||||
if (!facility) {
|
||||
const canonicalSlug = await getCanonicalSlug(slug);
|
||||
if (canonicalSlug) {
|
||||
permanentRedirect(`/golfbaner/${canonicalSlug}`);
|
||||
}
|
||||
|
||||
notFound();
|
||||
}
|
||||
|
||||
const facilityJsonLd = createFacilityJsonLd(facility);
|
||||
|
|
|
|||
Loading…
Reference in a new issue