Integrating pages - handling Head data and 404

Hi all,

I’m fairly new to Qwik, Qwik City, and Builder so apologies in advance if this is a dumb question.

Working through the tutorials about integrating pages and using the demo code provided, I have two questions:

  1. What is the best method of accessing the Builder page title and description and moving those to the head export?

  2. If you implement the […slug] folder and index.tsx file, doesn’t this mean there will never be a 404 handled by Qwik City? Is there a way to check whether the page exists in Builder, and if not fallback to a 404?

Appreciate any feedback.

I may have solved the first issue by moving the getContent call into a loader, which then allows me to use resolveValue in the head export to get the data from getContent there. Here’s the code in case helpful to anyone else.

import { component$, Resource } from "@builder.io/qwik";
import type { DocumentHead } from "@builder.io/qwik-city";
import { loader$ } from "@builder.io/qwik-city";
import { getContent, RenderContent, getBuilderSearchParams } from "@builder.io/sdk-qwik";
import { BUILDER_PUBLIC_API_KEY } from "~/lib/const";

export const BUILDER_MODEL = 'page';

export const usePageContent = loader$(({pathname, query}) => {
  return getContent({
    model: BUILDER_MODEL,
    apiKey: BUILDER_PUBLIC_API_KEY,
    options: getBuilderSearchParams(query),
    userAttributes: {
      urlPath: pathname || '/',
    },
  });
})

export default component$(() => {
  const builderContentRsrc = usePageContent();

  return (
    <Resource
      value={builderContentRsrc}
      onPending={() => <div>Loading...</div>}
      onResolved={(content) => (
        <RenderContent
          model={BUILDER_MODEL}
          content={content}
          apiKey={BUILDER_PUBLIC_API_KEY}
        />
      )}
    />
  );
});

export const head: DocumentHead = ({resolveValue}) => {
  const content = resolveValue(usePageContent);
  return {
    title: content?.data?.title,
    meta: [
      {
        name: 'description',
        content: content?.data?.description, 
      }
    ]
  };
};