question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Pass config to adapters and allow modification and passing back to builder.

See original GitHub issue

Feature 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:

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:closed
  • Created 2 years ago
  • Comments:12 (5 by maintainers)

github_iconTop GitHub Comments

1reaction
ignatiusmbcommented, Aug 21, 2021

Adapters adapt now have access to the full config, https://kit.svelte.dev/docs#writing-an-adapter

1reaction
ReeceMcommented, Mar 25, 2021

A PR would be great if you’re up to it, thanks — aside from the one-line change in prerender.js mentioned above I think we’d just need to edit this validate function…

If I can have a look tomorrow ? I can give a better answer as it’s early morning here :)

Read more comments on GitHub >

github_iconTop Results From Across the Web

File-based Configurations - Apache Commons
In Commons Configuration a specialized configuration builder implementation is responsible for the creation of file-based configuration objects ...
Read more >
Create and configure TableAdapters - Visual Studio (Windows)
Run the TableAdapter Configuration Wizard to create or edit TableAdapters and their associated DataTables. You can configure an existing ...
Read more >
Advanced Configuration Tricks - tutorials - Laminas Docs
Sometimes you want to change application configuration to load things such as database adapters, log writers, cache adapters, and more based on the...
Read more >
Adapter Code - Itential
The Adapter Builder makes a method in this file for each action within the API. ... It should not be modified because when...
Read more >
Binding adapters - Android Developers
A static binding adapter method with the BindingAdapter annotation allows you to customize how a setter for an attribute is called.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found