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

New hook onRenderContent(): generate non-HTML files with arbitrary content #1525

Open
iacore opened this issue Feb 27, 2024 · 12 comments
Open
Labels
enhancement ✨ New feature or request low-prio 🐌

Comments

@iacore
Copy link

iacore commented Feb 27, 2024

Description

I hope vike can generate files that is not HTML and without injected tags.

The requirements are

  • The generation script need to work inside vite context (need access to vite API like import.meta.glob)
  • Work in development mode (can see the file on development server)
  • Work in production build (the file is generated correctly with a chosen filename without .html)

Related: #1522 #1524

Use Cases

@iacore iacore added the enhancement ✨ New feature or request label Feb 27, 2024
@brillout
Copy link
Member

Use Cases

So far the recommendation for these two use cases are to use a post-build script (without using Vite).

I agree that being able to use Vite for transpiling the post-build script would be nice. In the meantime, can you fallback to use other utilities such as ts-node (and fast-glob instead of import.meta.glob())?

Why not adding a new CLI command $ vike run path-to/some-script.ts instead of your proposal?

Or maybe a new Vike hook onAfterBuild(), but that would work only for build. Actually, how about a new generic hook onRenderContent() that can generate content that isn't HTML.

Spontaneously I like $ vike run and onRenderContent() most. But I'm happy to discuss this.

Also, what do other frameworks do to support these two use cases? Can someone dig into that?

@iacore
Copy link
Author

iacore commented Feb 27, 2024

onRenderContent is best, I think. Still need to offer an option to set the output path, though. It would be nice if the API allows access to pageContext from other files like page title, which will make sitemap generation easier.

Also, what do other frameworks do to support these two use cases? Can someone dig into that?

lume allows generating arbitrary file content. lume has a sitemap plugin.

To set the page URL in lume, you simply do

export const url = "/feed.json";

or

---
url: /blog/example.md
---

# Page Content Here

Eleventy allows generating arbitrary content too. It has a RSS plugin which only provides data and needs the user to provide a template for it. You can use the RSS plugin to generate a site map with the correct template.

@brillout
Copy link
Member

Still need to offer an option to set the output path, though.

Or how about using Filesytem Routing as usual?

It would be nice if the API allows access to pageContext from other files

You shouldn't do that in dev, see https://vike.dev/markdown#metadata. Upon pre-rendering you can already access that, although it's currently hidden behind an internal API: pageContext._prerenderContext.pageContexts.

It makes sense that SSGs like Lume and Eleventy supports that use case. I was more wondering about SSR frameworks such as Next.js or Nuxt.

@iacore
Copy link
Author

iacore commented Feb 28, 2024

Or how about using Filesytem Routing as usual?

How do I generate dist/client/feed.json but not dist/client/feed.json/index.html?

Also, I can't name a folder feed.json because vite complains about trying to load the folder as JSON. (you can create feed.json/+Page.tsx to test it out)

It makes sense that SSGs like Lume and Eleventy supports that use case. I was more wondering about SSR frameworks such as Next.js or Nuxt.

In those frameworks, the Atom feed is usually an API route, and vike made the decision to not support API routes (I read that in the docs).

@brillout
Copy link
Member

brillout commented Feb 29, 2024

How do I generate dist/client/feed.json but not dist/client/feed.json/index.html?

Vike wouldn't create an .html file when the content is generated with onRenderContent().

Also, I can't name a folder feed.json because vite complains about trying to load the folder as JSON. (you can create feed.json/+Page.tsx to test it out)

You could use a Route String.

In those frameworks, the Atom feed is usually an API route, and vike made the decision to not support API routes (I read that in the docs).

You can use an Express.js/Fastify/Hono/... route instead. Note that we're currently working on #562. I stand to be corrected, but I believe that once #562 is implemented then API routes would be an inferior design in all regards.

@iacore
Copy link
Author

iacore commented Feb 29, 2024

Vike wouldn't create an .html file when the content is generated with onRenderContent().

I need a static page! onRenderContent won't generate a JSON file, or can it?

You could use a Route String.

A route string of /feed.json generates /feed.json/index.html

In #562, you linked to vite-node. I'll try writing a script with that. Thanks for the idea!

@brillout
Copy link
Member

brillout commented Mar 1, 2024

@iacore It will create a file, it just won't be a .html one. If you set the Route String to end with .json so will the generated file.

@brillout brillout changed the title Generate file with arbitrary content at arbitrary output path New hook onRenderContent(): generate non-HTML files with arbitrary content Mar 1, 2024
@brillout
Copy link
Member

brillout commented Mar 1, 2024

Since there is a workaround and there are only two use cases for it, I'm labeling this as low-prio 🐌.

That said, the priority can be increased by:

  • Reacting to the original post of this issue with "👍".
  • Further elaborating use cases. (The more we can see how much added value it adds, the higher we'll increase its priority.)
  • Creating a PR. (For example, if your PR showcases that it's easy to implement, then we'll merge it. That said, keep in mind that we may reject your PR if reviewing it would take too much time.)
  • Does any React/Vue/Solid SSR framework out there support your use case? If yes that also increases the priority.
  • Sponsoring Vike

@iacore
Copy link
Author

iacore commented Mar 2, 2024

The vite-node method worked! Do we document the vite-node usage somewhere?

I haven't tried onRenderClient. Is it strange that onRenderClient renders to a file on the server?

@brillout
Copy link
Member

brillout commented Mar 2, 2024

I haven't tried onRenderClient. Is it strange that onRenderClient renders to a file on the server?

Apologies I meant onRenderContent() not onRenderClient(). I've edited my comment (and yours).

The vite-node method worked! Do we document the vite-node usage somewhere?

It isn't. I think it's fine for now as there are currently a lot of higher priorities regarding the docs.

@iacore
Copy link
Author

iacore commented Mar 2, 2024

Apologies I meant onRenderContent() not onRenderClient(). I've edited my comment (and yours).

I assume you meant onRenderHtml. I can't find a onRenderContent hook.

@iacore It will create a file, it just won't be a .html one. If you set the Route String to end with .json so will the generated file.

as of vike 0.4.165, it generates xxx.json/index.html rather than xxx.json, with the route string below:

// +route.ts
export default '/test.json'

@brillout
Copy link
Member

Interesting approach by SvelteKit: https://kit.svelte.dev/docs/seo#manual-setup-sitemaps

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement ✨ New feature or request low-prio 🐌
Projects
None yet
Development

No branches or pull requests

2 participants