BuilderIO / builder

Visual Development for React, Vue, Svelte, Qwik, and more
https://builder.io
MIT License
7.51k stars 939 forks source link

SSG support for builder generated pages #2890

Open sem4phor opened 10 months ago

sem4phor commented 10 months ago

Describe the bug Qwik + Builder + SSG Adapter does not really work well.

I want to use builder's feature with qwik to create new pages from builder.io. That requires the [...index] route to render the builder content. However there is no way documented on how to statically generate those pages. The onStaticGenerate function allows to return url params but the generated urls are only /undefined/index.html. Would be great to have this working.

To Reproduce Steps to reproduce the behavior:

  1. Set up a fresh qwik + builder + ssg adapter application
  2. Run npm run build
  3. --> No index route is generated
  4. Add onStaticGenerate method as documented in builder docs and return something for every page entry (use fetchEntries)
  5. --> /undefined/index.html gets generated

Expected behavior I mean it's propably more of a feature request but it would be great if you could fetch the pages from builder and then generate them:

// src/routes/[...index]/index.tsx
import { fetchEntries } from "@builder.io/sdk-qwik";
...
export const onStaticGenerate: StaticGenerateHandler = async () => {
  const entries = await fetchEntries({
    model: BUILDER_MODEL,
    apiKey: import.meta.env.PUBLIC_BUILDER_API_KEY,
  })

  return {
    params: entries.results.map((e) => ({
      // TODO: instead of id use page name
      id: e.id!
    }))
  }
}
...
mhuretski commented 9 months ago

for [...path] route

export const onStaticGenerate: StaticGenerateHandler = async () => {
  const res = await fetchEntries({
    model: 'page',
    limit: 0,
    options: {
      fields: 'data.url',
    },
  })

  const params =
    (res
      ?.map((value) => {
        return { path: value.data?.url }
      })
      .filter(({path}) => path && path !== '/') as []) || []

  return {
    params,
  }
}

export const useBuilderData = routeLoader$(async (re) => {
  const path = re.params.path

  return fetchOneEntry ... with path
}

and treat index separately, create index.tsx file in routes and

export const useHomepageData = routeLoader$(async (re) => {
  return fetchOneEntry({
    model: 'page',
    urlPath: '/',
    searchParams: re.url.searchParams,
  })
})

so in route path you're getting only page urls when inside your page you're fetching whatever you want