Pass config to adapters and allow modification and passing back to builder.
See original GitHub issueFeature being requested
Is your feature request related to a problem? Please describe.
So using SvelteKit with Prismic as my CMS (might apply for most), but if I have say blog pages, or when their is support for their Slicemachine, their is the pattern of using a page that has a [uid].svelte
format.
When in a Next.js application, you can normally use the static paths function to prerender the pages and fetch the endpoints.
Using the SvelteKit, I noticed that their isn’t that functionality, other than the svelte:prefetch
in link tags. If you happen to not have a link pointing to a specific page, the prerendering actually doesn’t load the page, this is if you are exporting a complete static build, the static adapter.
This presents the issue of 404s naturally.
If one wanted to prerender the pages, you have to make sure the links are there, but if there aren’t any there has to be a way, either when generating static files or in the config.
Description of Solution
Describe the solution you’d like
A clear and concise description of what you want to happen.
It would be nice to either have a function similar to the load()
one that can be defined in a page that hasn’t got a fixed name, one that can be called and retrieve all the possible paths for that route, similar to Next, although to be similar might not be wanted.
Or
The other solution would be that there an be the addition of a static adapter that can be used to call and build routes and then add those at build time to the config.kit.prerender.pages
array. Or that the pages thing can accept a callback/promise and call it to get the list dynamically.
Describe alternatives you’ve considered A clear and concise description of any alternative solutions or features you’ve considered.
I have tried to call the api endpoint for the CMS inside the config file and build the list of pages and set that in the export, in various ways, but obviously because the library is async and await structured, it doesn’t work well.
The other alternative, with a bit of modification to the source of SvelteKit was to use an adapter, making it a specific thing to get the data.
I looked at the source for the adapter part of the config file and how it is handling the config, so I edited the following output files in the source:
inside index5.js
+ /** @param {{ force: boolean, dest: string, config: Object }} opts */
+ async prerender({ force = false, dest, config }) {
if (this.#config.kit.prerender.enabled) {
await prerender({
out: dest,
force,
cwd: this.#cwd,
+ config: Object.assign(this.#config, config),
log: this.log
});
}
}
Then in the adapt function:
/**
* @param {{ cwd?: string, verbose: boolean }} opts
*/
async function adapt(config, { cwd = process.cwd(), verbose }) {
const { name, adapt } = config.kit.adapter;
console.log($.bold().cyan(`\n> Using ${name}`));
const log = logger({ verbose });
const builder = new Builder({ cwd, config, log });
+ await adapt(builder, config);
log.success('done');
}
The files that that would have come from in src are:
- https://github.com/sveltejs/kit/blob/master/packages/kit/src/core/adapt/index.js
- https://github.com/sveltejs/kit/blob/master/packages/kit/src/core/adapt/Builder.js
Those changes from my understanding may or may not make it that a person can adjust the config via the adapter and builder, similar to the access one has to webpack and the config in Next.js. Which is really nice.
The changes I made basically allow default fallback to normal functionality. But allows one to adjust the prerender function by allowing another option in the methods parameters.
Result on end user side
The result of an adapter that is built would be the following which is for Prismic:
module.exports = function ({ dest = 'build', prefetch = null } = {}) {
/** @type {import('@sveltejs/kit').Adapter} */
const adapter = {
name: '@reecem/adapter-prismic',
async adapt(builder, config) {
if (!prefetch) {
await builder.prerender({
force: true,
dest: dest
})
return;
}
let modifiedConfig = await prefetch(config);
await builder.prerender({
force: true,
dest: dest,
modifiedConfig
});
}
};
return adapter;
};
Then in the config file, I can do the following:
const static = require('@sveltejs/adapter-static');
const prismic = require('./adapter-prismic');
const pkg = require('./package.json');
const Prismic = require('@prismicio/client');
const Client = Prismic.client("https://xyz.cdn.prismic.io/api/v2");
const linkResolver = (doc) => {
if (doc.type === 'blog_post') {
return `/blog/${doc.uid}`
}
return `/${uid}`;
}
/** @type {import('@sveltejs/kit').Config} */
module.exports = {
kit: {
// By default, `npm run build` will create a standard Node app.
// You can create optimized builds for different platforms by
// specifying a different adapter
adapter: prismic({
prefetch: async (config) => {
let query = await Client.query(Prismic.Predicates.at('document.type', 'blog_post'));
let result = query.results.map(linkResolver);
config.kit.prerender.pages.push(...result)
return config;
}
}),
// hydrate the <div id="svelte"> element in src/app.html
target: '#svelte',
prerender: {
crawl: true,
enabled: true,
force: true,
pages: ['*'],
},
vite: {
ssr: {
noExternal: Object.keys(pkg.dependencies || {})
}
}
}
};
The result is that I can now get the .json version, the html version and all pages that are using a slug to generate even if the link doesn’t exist. But can still control what pages.
How important is this feature to you? Note: the more honest and specific you are here the more we will take you seriously.
To me this is important when using Prismic as I can build the pages as very static html files or even the json is already there, or another CMS that would allow the pages and having their ID’s dictate the pages that can be rendered.
Having a way to build those pages, as when exporting the build and using the generated site, even with the static plugin, it would give me odd data. Like not actual pages and anything that were blog pages gave 404’s on Netlify.
I battled to understand what way would work with prerendering pages outside of the prefetch links and where to implement the similar functionality that would allow the routes to be generated. I may not understand the prefetchRoutes() function as I get the error that it cannot be used on the server.
I know that there are a few people in the Prismic community that are also wanting to use Svelte more with it, so it may help them too.
Additional context Add any other context or screenshots about the feature request here.
N/A
Issue Analytics
- State:
- Created 2 years ago
- Comments:12 (5 by maintainers)
Top GitHub Comments
Adapters
adapt
now have access to the fullconfig
, https://kit.svelte.dev/docs#writing-an-adapterIf I can have a look tomorrow ? I can give a better answer as it’s early morning here :)