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

Notes for using with Vercel adapter, plus an alternative solution #5

Open
leoj3n opened this issue Feb 13, 2024 · 1 comment
Open

Comments

@leoj3n
Copy link

leoj3n commented Feb 13, 2024

Here are some hopefully helpful notes if you are just getting started with this and using Vercel adapter...

Having a root +layout.js like:

export const prerender = true;

And a svelte.config.js like:

import adapter from '@sveltejs/adapter-vercel';
import htmlMinifierAdaptor from "sveltekit-html-minifier";

/** @type {import('@sveltejs/kit').Config} */
const config = {
	kit: {
		adapter: htmlMinifierAdaptor(adapter(), { pages: ".svelte-kit/output" }),
	}
};

export default config;

I was getting an error like:

[...]
.svelte-kit/output/server/index.js                                      92.07 kB

Run npm run preview to preview your production build locally.

> Using sveltekit-html-minifier, @sveltejs/adapter-vercel
  ✔ done
✓ built in 10.85s
node:fs:601
  handleErrorFromBinding(ctx);
  ^

Error: ENOENT: no such file or directory, open '.svelte-kit/output/index.html'

So, I changed the config to:

import adapter from '@sveltejs/adapter-vercel';
import htmlMinifierAdaptor from "sveltekit-html-minifier";

/** @type {import('@sveltejs/kit').Config} */
const config = {
	kit: {
		adapter: htmlMinifierAdaptor(adapter(), { pages: ".svelte-kit/output/prerendered/pages" }),
	}
};

export default config;

Notice svelte-kit/output/prerendered/pages vs what I tried originally .svelte-kit/output.

This made it work; just thought I'd share if it helps anyone else using Vercel adapter.

Also note I learned you have to be using export const prerender = true; or else there is nothing to minify during "prerender".

Furthermore, I found this alternate method working using the html-minifier package directly in ./src/hooks.server.ts:

// ./src/hooks.server.ts
import { i18n } from '$lib/i18n';
import { minify } from 'html-minifier';
import { building } from '$app/environment';
import { sequence } from '@sveltejs/kit/hooks';

const minification_options = {
	collapseBooleanAttributes: true,
	collapseWhitespace: true,
	conservativeCollapse: true,
	decodeEntities: true,
	html5: true,
	ignoreCustomComments: [/^#/],
	minifyCSS: true,
	minifyJS: true,
	removeAttributeQuotes: true,
	removeComments: false, // some hydration code needs comments, so leave them in
	removeOptionalTags: true,
	removeRedundantAttributes: true,
	removeScriptTypeAttributes: true,
	removeStyleLinkTypeAttributes: true,
	sortAttributes: true,
	sortClassName: true
};

/** @type {import('@sveltejs/kit').Handle} */
async function minify_handle({ event, resolve }) {
	let page = '';

	return resolve(event, {
		transformPageChunk: ({ html, done }) => {
			page += html;
			if (done) {
				return building ? minify(page, minification_options) : page;
			}
		}
	});
}

export const handle = sequence(i18n.handle(), minify_handle);

I think using this adapter plugin is a bit more elegant than that however.

Just sharing if it helps anyone, so feel free to make it a closed issue; and thanks for sharing this adapter adapter.

@ntsd
Copy link
Owner

ntsd commented Feb 17, 2024

Thank you for sharing. The adaptor only works with prerender because it will minify the rendered HTML page.
If The prerender is false It will render during the SSR response the hooks way should be correct.
Thank you for clarifying I will not in the README

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants