Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

@astrojs/markdoc v0.3.1 (reprise of issue #7170): Markdoc tag rendering Astro component breaks when component uses getEntryBySlug() #7317

Closed
1 task
paulrudy opened this issue Jun 6, 2023 · 8 comments · Fixed by #7468
Assignees
Labels
- P3: minor bug An edge case that only affects very specific usage (priority) pkg: markdoc Related to the `@astrojs/markdoc` package (scope)

Comments

@paulrudy
Copy link
Contributor

paulrudy commented Jun 6, 2023

What version of astro are you using?

2.6.0

Are you using an SSR adapter? If so, which one?

None

What package manager are you using?

pnpm

What operating system are you using?

Mac

What browser are you using?

Chrome, Safari

Describe the Bug

This is a reprise of issue #7170, which shows up again with @astrojs/markdoc v0.3.1. Details basically identical to the previous issue, except that this time around, local Astro in dev mode doesn't seem to throw an error. In Stackblitz, it does.

This is a very particular bug that showed up with @astrojs/markdoc v0.3.1 , when all of the following are true:

  1. @astrojs/markdoc is v0.3.1
  2. Pages are served from a content collection of at least two .mdoc files.
  3. markdoc.config.mjs imports an Astro component (for the purpose of defining a tag, although no tag actually needs to be defined—or used in any .mdoc file)
  4. The Astro component uses getEntryBySlug() to access data from another content collection (the new getEntry() also produces the error)

In local dev mode, I'm not seeing an error, the page just doesn't render. In Stackblitz looks like:

  error   Unexpected error while rendering pages → index.mdoc.
Error
    at AstroError (<anonymous>)
    at <anonymous> (<anonymous>)
    at render (<anonymous>)

Pages render as expected after downgrading to v0.3.0, or when any of the other items above are false!

Link to Minimal Reproducible Example

https://stackblitz.com/edit/github-pq3pgo-xieer6?file=package.json

Participation

  • I am willing to submit a pull request for this issue.
@bholmesdev bholmesdev self-assigned this Jun 6, 2023
@bholmesdev bholmesdev added - P4: important Violate documented behavior or significantly impacts performance (priority) pkg: markdoc Related to the `@astrojs/markdoc` package (scope) - P3: minor bug An edge case that only affects very specific usage (priority) and removed - P4: important Violate documented behavior or significantly impacts performance (priority) labels Jun 6, 2023
@bholmesdev
Copy link
Contributor

bholmesdev commented Jun 7, 2023

Hm, this is proving a very weird nut to crack. It looks like the circular dependency of astro:content -> .mdoc file -> component -> astro:content is causing a memory issue in Vite. If you just have one content collection entry, the Markdoc module looks fine:

{
  getHeadings: [function],
  Content: [function],
  [Symbol(Symbol.toStringTag)]: 'Module' }
}

But as soon as there's two or more files in that collection, it becomes this:

{ [Symbol(Symbol.toStringTag)]: 'Module' }

Note these logs are coming from the content runtime file, which pull an import off of an import.meta.glob for all Markdoc files.

Seems like Vite is throwing away the keys in the module 😕 Paging @bluwy if he has any ideas

@bholmesdev
Copy link
Contributor

bholmesdev commented Jun 7, 2023

As a workaround, I'd try passing getEntry as a Markdoc variable to "inject" into your content. This breaks the circular dependency issue:

// markdoc.config.mjs
import { defineMarkdocConfig } from '@astrojs/markdoc/config';
import Aside from './src/components/Aside.astro';

export default defineMarkdocConfig({
	tags: {
		aside: {
			render: Aside,
			attributes: {
				name: { type: String },
				getAside: { type: Function },
			},
		},
	},
});
---
// src/content/[...slug].astro
import BaseLayout from '../layouts/Layout.astro';
import { getEntry, getEntryBySlug } from 'astro:content';
const { slug } = Astro.params;
const page = await getEntryBySlug('pages', slug === undefined ? 'index' : slug);
const { Content } = await page!.render();
---

<BaseLayout title={page!.data.title}>
	<Content getAside={(name: string) => getEntry('asides', name)} />
</BaseLayout>
<!--src/content/pages/index.mdoc-->
{% aside name="1" getAside=$getAside /%}
---
// src/components/Aside.astro
const { getAside, name } = Astro.props;
const aside = await getAside(name);
const asideTitle = aside.data.title;
---

<div>{asideTitle}</div>

@paulrudy
Copy link
Contributor Author

paulrudy commented Jun 7, 2023

Thanks for your sleuthing! I won't have time to implement this for a few days, but I'll try it out then, if there isn't already a new solution by then 👍🏼

@paulrudy
Copy link
Contributor Author

paulrudy commented Jun 14, 2023

@bholmesdev, your workaround works well when using the component as a markdoc custom tag in markdoc files. However, I can't figure out how to implement your workaround so that the component continues to work in .astro files as well. I thought I could perhaps do something to use getEntry() if it's not being called from a markdoc file, like this:

---
// src/components/Aside.astro
import { getEntry } from 'astro:content';
const { getAside, name } = Astro.props;
const aside = getAside ? await getAside(name) : getEntry('asides', name);
const asideTitle = aside.data.title;
---

<div>{asideTitle}</div>

But that doesn't work—it throws the same error as in the original post. Any ideas would be welcome!

@paulrudy
Copy link
Contributor Author

paulrudy commented Jun 15, 2023

Apologies, I am actually able to use the workaround with Astro files as long as I don't "mention" getEntry() in Aside.astro (as that seems to invoke the circular logic you found), but it requires passing getEntry() as a variable through multiple components (in my case, from [...slug].astro to BaseLayout.astro to Sidebar.astro), which makes this workaround a bit precarious when trying to replicate normal functioning of getEntry()

@bholmesdev
Copy link
Contributor

bholmesdev commented Jun 26, 2023

Hey @paulrudy! The new render API is up on a preview release. Just verified it fixes your minimal repro locally. When you have time, do you mind:

  1. Installing these versions in your test project
npm i astro@latest @astrojs/markdoc@next--markdoc-config-changes
  1. Updating your Markdoc config as described by the changeset here?

@paulrudy
Copy link
Contributor Author

paulrudy commented Jun 27, 2023

Hey @bholmesdev, it works! Woop woop! Thank you! Glad this change helps with multiple other stuff as well.

@bholmesdev
Copy link
Contributor

@paulrudy Woooo! Just merged. You'll see it once Markdoc v0.4.0 is live 🥳

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
- P3: minor bug An edge case that only affects very specific usage (priority) pkg: markdoc Related to the `@astrojs/markdoc` package (scope)
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants