Builder
TsContentPage
Overview
The TsContentPage component is a specialized connector for the page model in Builder.io. It streamlines the integration and rendering of page-specific content, ensuring efficient data handling and seamless dynamic updates tailored for the page model.
Component Code
<template>
<div :style="{ backgroundColor: `${rootStore.page_background_color}` }">
<div v-if="content && api_key">
<Content
model="page"
:content="content"
:api-key="api_key"
:customComponents="getRegisteredComponents()"
/>
</div>
<div
v-else
role="status"
class="flex items-center justify-center h-56 max-w-sm bg-gray-300 rounded-lg animate-pulse dark:bg-gray-700 m-auto my-20"
style="height: 400px"
>
<svg
class="w-10 h-10 text-gray-200 dark:text-gray-600"
aria-hidden="true"
xmlns="http://www.w3.org/2000/svg"
fill="currentColor"
viewBox="0 0 16 20"
>
<path
d="M5 5V.13a2.96 2.96 0 0 0-1.293.749L.879 3.707A2.98 2.98 0 0 0 .13 5H5Z"
/>
<path
d="M14.066 0H7v5a2 2 0 0 1-2 2H0v11a1.97 1.97 0 0 0 1.934 2h12.132A1.97 1.97 0 0 0 16 18V2a1.97 1.97 0 0 0-1.934-2ZM9 13a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-2a2 2 0 0 1 2-2h2a2 2 0 0 1 2 2v2Zm4 .382a1 1 0 0 1-1.447.894L10 13v-2l1.553-1.276a1 1 0 0 1 1.447.894v2.764Z"
/>
</svg>
<span class="sr-only">Loading...</span>
</div>
</div>
</template>
<script setup lang="ts">
import { fetchOneEntry, Content, isPreviewing } from "@builder.io/sdk-vue";
import { REGISTERED_COMPONENTS } from "~/utils/init-builder";
import { BuilderService } from "../../services/builder.service";
import { datadogLogs } from "@datadog/browser-logs";
import { useI18n } from "vue-i18n";
const { t } = useI18n();
const route = useRoute();
const config = useRuntimeConfig();
const rootStore = useRootStore();
const content = ref();
const page_title = ref("Toolstation");
const api_key = config.public.builderApiKey;
try {
const route_name_array = route.name.split("___");
let path = route.path;
if (route_name_array.length > 1) {
path = route.path.replace(route_name_array[1] + "/", "");
path = path.replace(route_name_array[1], "");
}
let options = {
fields: "data",
};
async function fetchPageContent(urlPath: string) {
let userAttributes = {
urlPath,
};
const { data } = await useAsyncData("builderPage", () =>
new BuilderService(api_key).getItem("page", userAttributes, options)
);
if (data.value.data.backgroundColor) {
rootStore.page_background_color = null;
rootStore.page_background_color = data.value.data.backgroundColor;
}
return data.value;
}
content.value = await fetchPageContent(path);
const capitalizedPageTitle = computed(() => {
const processTitle = (title: string) => {
// Replace hyphens with spaces
return title.replace(/-/g, " ");
};
if (content.value?.data?.seoMetaTags?.title) {
return processTitle(content.value.data.seoMetaTags.title);
} else if (content.value?.data?.title) {
return processTitle(content.value.data.title);
}
return "Toolstation"; // default title
});
if (!content.value) {
content.value = await fetchPageContent("/404");
useHead(() => ({
status: 404,
title: t("pageNotFound", "Page not found"),
}));
throw createError({
statusCode: 404,
statusMessage: "404 - Page Not Found",
});
/*datadogRum.addError('Page Not Found', {
error: new Error('Page Not Found'),
url: route.path,
statusCode: 404,
});*/
datadogLogs.logger.error("404 - Page Not Found", {
url: route.path,
referrer: document.referrer, // Add the referral path
statusCode: 404,
});
}
useHead({
title: capitalizedPageTitle,
meta: [
{
name: "description",
content:
(content.value &&
content.value.data &&
content.value.data.seoMetaTags &&
content.value.data.seoMetaTags.description) ||
"Beste gereedschap & bouwbenodigdheden voor de professional.",
},
{
name: "keywords",
content:
(content.value &&
content.value.data &&
content.value.data.seoMetaTags &&
Array.isArray(content.value.data.seoMetaTags.keywords) &&
content.value.data.seoMetaTags.keywords.length > 0 &&
content.value.data.seoMetaTags.keywords.toString()) ||
"Toolstation",
},
],
});
} catch (e) {
useErrorHandler(e);
}
onMounted(() => {
useCompareStore().clearCompareProducts();
});
const getRegisteredComponents = () => {
return REGISTERED_COMPONENTS;
};
</script>
Usage
<template>
<TsContentPage />
</template>