Add a example mupdf.js with Sveltekit
Add a example mupdf.js with Sveltekit
Hey, after some tinkering I got it to work:
1st step: add mupdf to the dependencies
npm i mupdf
2nd step: change module resolution in tsconfig.json
tsconfig.json
{
// ....
"compilerOptions": {
// ....
"moduleResolution": "nodenext",
"module": "nodenext"
}
// ....
}
3rd step: mupdf will try to fetch the wasm binary from node_modules/.vite/dist/mupdf_wasm.wasm. This is however by default not the place where the binary is located. That's why I used the vite-plugin-static-copy to mitigate this:
npm i vite-plugin-static-copy
vite.config.ts
import { sveltekit } from '@sveltejs/kit/vite';
import { defineConfig } from 'vite';
import { viteStaticCopy } from 'vite-plugin-static-copy';
export default defineConfig({
optimizeDeps: {
esbuildOptions: {
target: 'esnext'
}
},
build: {
target: 'esnext'
},
plugins: [
viteStaticCopy({
targets: [
{
src: 'node_modules/mupdf/dist/mupdf-wasm.wasm',
dest: 'node_modules/.vite/deps',
}
]
}),
sveltekit()
]
});
hope this helps!
This is my approach:
bun add mupdf- vite.config.ts
import { sveltekit } from "@sveltejs/kit/vite";
import { defineConfig } from "vite";
import tailwindcss from "@tailwindcss/vite";
export default defineConfig({
optimizeDeps: {
exclude: ["mupdf"],
esbuildOptions: {
target: "esnext", //esnext is subject to change, es2022 should work too (untested)
},
},
build: {
target: "esnext", //same
},
plugins: [sveltekit(), tailwindcss()],
});
And here is an example:
- +page.server.ts
import type { PageServerLoad } from "./$types";
import { read } from "$app/server";
import myImportedPDF from "$lib/myDocument.pdf";
export const load = (async () => {
return {
myReturnedPDF: await read(myImportedPDF).arrayBuffer(),
};
}) satisfies PageServerLoad;
- +page.svelte
<script lang="ts">
import * as mupdfjs from "mupdf/mupdfjs";
import type { PageProps } from "./$types";
let { data }: PageProps = $props();
let pdf = mupdfjs.PDFDocument.openDocument(data.myReturnedPDF, "application/pdf");
</script>
<!--Simple HTML preview of the first page, not a 1:1 with the PDF -->
<div class="w-fit bg-white">
{@html pdf
.loadPage(0)
.toStructuredText("preserve-whitespace,preserve-images,preserve-spans")
.asHTML(0)
.replace(/<p style="([^"]*)">/g, '<p style="$1; position: absolute;">')}
</div>
my tsconfig.json uses the default "moduleResolution": "bundler"
I have yet to test an actual deployment, but in local development everything seems to work fine
Seems more idiomatic. Good job!
You should probably clarify if you want an example using server side rendering, client side rendering, or both!