Closed oliverlynch closed 10 months ago
Hey @oliverlynch π
This is currently a limitation of the way Astro and Bookshop interact β though we should certainly display this error better. Since Bookshop previews in the browser without access to your source files, interacting with your content collections directly isn't possible from within a component.
We have some future plans to help support this β but there isn't anything in place just yet.
If we don't have a solution for this, does someone have a workaround alternative? I can't conditionally import a component file so not sure if there is a simple solution or if this needs to be complex.
I managed to work around this by getting all of my collection information outside of the bookshop:live
element, then passing it in; for example generating getStaticPaths()
with getCollection
then passing my static paths list as a prop allowing me to generate a navigation component inside bookshop:live
.
I managed to work around this by getting all of my collection information outside of the
bookshop:live
element, then passing it in; for example generatinggetStaticPaths()
withgetCollection
then passing my static paths list as a prop allowing me to generate a navigation component insidebookshop:live
.
I used Astro middleware to pass collections to Astro.locals to get around this issue. Just posting this if others are running into the same issue.
I managed to work around this by getting all of my collection information outside of the
bookshop:live
element, then passing it in; for example generatinggetStaticPaths()
withgetCollection
then passing my static paths list as a prop allowing me to generate a navigation component insidebookshop:live
.I used Astro middleware to pass collections to Astro.locals to get around this issue. Just posting this if others are running into the same issue.
Hi @edmeehan , can you post you code on this please? I'm not familiar with astro middleware but this could really help me out.
Thanks! :)
Update on this;
I get the error even when 'astro:content' is being used outside the bookshop:live component. I have a Layout wrapping it, which uses 'astro:content' and 'astro:transitions':
<Layout>
<RenderBookshop
bookshop:live
settings={settings}
preview={preview}
collections={collections}
/>
</Layout>
For me it causes bookshop:live to bring more problems than benefit unfortunately.
I used Astro middleware to pass collections to Astro.locals to get around this issue. Just posting this if others are running into the same issue.
Great idea to use middleware - I've moved my navigation generation to middleware which means I no longer need to pass everything down to my site navigation component. This is probably the best workaround for now, although astro can't seem to read the type declarations I've set for local in env.d.ts...
can you post you code on this please? I'm not familiar with astro middleware but this could really help me out.
The basic example on astro docs for middleware works pretty much out of the box with bookshop and the docs go more depth than I can add here, but in my middleware I am getting the "pages" collection to generate navigation, and attaching it to locals so it can be accessed anywhere. I am also attaching all of the collections to locals so that components can reference other pages without using astro:content.
import { defineMiddleware } from "astro:middleware";
import { getCollection, type CollectionEntry } from "astro:content";
import { collections } from "src/content/config";
export const onRequest = defineMiddleware(
async (ctx: Record<string, any>, next) => {
const pages = await getCollection("pages", (page) => {
return page.data.status === "online";
});
ctx.locals.tree = makeTree(pages, ctx.params.slug);
ctx.locals.collections = await getAllCollections();
return next();
}
);
The code inside the defineMiddleware function is run for each page that is generated, and anything that you attach to the locals will be available at Astro.locals
.
I get the error even when 'astro:content' is being used outside the bookshop:live component. I have a Layout wrapping it, which uses 'astro:content' and 'astro:transitions':
Thats strange, I've just tried adding both astro:content and astro:transitions into my layout, organised similarly to your setup:
<Layout {...props} {id} {paths} {currentPath}>
<Page bookshop:live contentBlocks={props.content_blocks} />
</Layout>
...and bookshop seems happy enough adding live editing. The only thing I could think of at the top of my head that might cause it is if you are passing the collections as a promise to the bookshop:live component, but I quickly tested it and bookshop didn't seem to mind.
@oliverlynch Thanks for the testing! Seems weird that I'm running into this issue then.
Something I also ran into when trying out the middleware appreach is that Astro.locals seems to be undefined in the CloudCannon live editing. No build errors this time, but I could not actually use the data. Have you also experienced this @oliverlynch ?
Something I also ran into when trying out the middleware appreach is that Astro.locals seems to be undefined in the CloudCannon live editing. No build errors this time, but I could not actually use the data. Have you also experienced this
I've tested a bunch of stuff out and it looks like you're right - both passing into the bookshop:live element with props and middleware result in undefined variables in the live editor...
It seems to me that in live mode only props defined within bookshop:live or in the component's __.bookshop.yml file are actually set. I thought the middleware setup had worked as bookshop compiled correctly and the navigation appeared in the live editor, but accessing Astro.locals inside bookshop:live is undefined as you have stated. I assumed passing props worked because it appears to work with the standard component properties normally, and I hadn't used any extra props - This should possibly be mentioned in the bookshop:live documentation.
This limitation is frustrating as centralising my navigation to middleware was partially to help create a page index component, but it won't work inside the live editor. For now I'll probably just use the ENV_BOOKSHOP_LIVE to display a placeholder during live editing, but obviously this is suboptimal. Hopefully we can get support for middleware and/or passing props within bookshop:live in the future.
Hi @silveltman, @oliverlynch, and @edmeehan π
Yesterday we released Bookshop 3.9.0 which includes support for using astro:content
inside Bookshop components in the visual editor. There is a small caveat that the collection item's content and render functions are just placeholders since we can't access the actual file in the visual editor. Otherwise all the collection item's data/frontmatter will be available and any build issues should be resolved.
Hi @Tate-CC ,
Sounds awesome! However, I just tried it out and my components are not rendering. Just to be sure, do the component actually work with 'astro:content' OR does the live editor skip these components and render the rest?
I'm having an issue in the bookshop generate step when trying to use getCollection from astro:content inside astro components. My astro build succeeds, but bookshop generate fails.
I can reproduce this in the sendit astro template by adding the import inside any of the .jsx components.
import { getCollection } from "astro:content";
Bookshop version 3.6.5
Console output: