#Using a single dynamic route that addresses 2 different content collections

2 messages · Page 1 of 1 (latest)

steel wharf
#

I have a [...slug].astro route that I'm trying to accommodate 2 different collections: post and page. The post collection has a reference to the author collection while the page collection does not.

Inside authorDate, I'm still getting a type error: object is possibly undefined for await getEntry("author", entry.data.author.slug).

How can I fix it?

import { getCollection, type CollectionEntry, getEntry } from "astro:content"
import MarkdownWrapper from "@/layouts/MarkdownWrapper.astro"

export async function getStaticPaths() {
  const postEntries = await getCollection("post")
  const pageEntries = await getCollection("page")

  const allEntries = [...postEntries, ...pageEntries]

  return allEntries.map((entry) => ({
    params: { slug: entry.slug },
    props: { entry, collection: entry.collection },
  }))
}

type EntryData = {
  author: {
    slug: string;
  };
};

type Props = {
  entry: CollectionEntry<"post" | "page"> & { data: EntryData };
  collection: CollectionEntry<"post" | "page">["collection"];
};

const { entry, collection } = Astro.props
const { Content } = await entry.render()

const authorData =
  collection === "post" && entry.data.author.slug
    ? (await getEntry("author", entry.data.author.slug)).data
    : undefined
steel wharf
#

I think I worked it out?

[...slug].astro

---
import { getCollection, type CollectionEntry } from "astro:content"
import MarkdownWrapper from "@/layouts/MarkdownWrapper.astro"

export async function getStaticPaths() {
  const postEntries = await getCollection("post")
  const pageEntries = await getCollection("page")

  const allEntries = [...postEntries, ...pageEntries]

  return allEntries.map((entry) => ({
    params: { slug: entry.slug },
    props: { entry },
  }))
}

type EntryData = {
  author: {
    slug: string;
  };
};

type Props = {
  entry: CollectionEntry<"post" | "page"> & { data: EntryData };
};

const { entry } = Astro.props
const { Content } = await entry.render();

---
<MarkdownWrapper frontmatter={entry}>
  <Content />
</MarkdownWrapper>