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

Cloudflare pages/worker issue - WebAssembly.instantiate(): Wasm code generation disallowed by embedder #307

Closed
davidtranjs opened this issue Mar 3, 2024 · 6 comments
Labels
help wanted Extra attention is needed

Comments

@davidtranjs
Copy link

Hi everyone,

Thanks for this awesome library.

Currently I have an NextJS app that deployed on Cloudflare pages, my app have an API route for generate OG Image in PNG format.

I use satori for generate SVG data and @resvg/resvg-wasm for convert SVG to PNG format.

Here is my code

import OgImageTemplate from "@/components/OgImageTemplate";
import satori from "satori";
import { Resvg, initWasm } from "@resvg/resvg-wasm";

export const runtime = "edge";

export default async function handler(req) {
  const fontRegular = await fetch(
    "https://cdn.jsdelivr.net/fontsource/fonts/poppins@latest/latin-400-normal.ttf"
  ).then((res) => res.arrayBuffer());

  const { searchParams } = new URL(req.url);
  const title = searchParams.get("title");
  const sub = searchParams.get("sub");

  const ogImage = await satori(<OgImageTemplate title={title} sub={sub} />, {
    width: 1200,
    height: 630,
    fonts: [
      {
        name: "Poppins",
        data: fontRegular,
        weight: 400,
        style: "normal",
      }
    ],
  });

  const wasmResponse = await fetch("https://unpkg.com/@resvg/[email protected]/index_bg.wasm");
  const wasmArrayBuffer = await wasmResponse.arrayBuffer();

  try {
    await initWasm(wasmArrayBuffer); // => this line throw the error

    const resvg = new Resvg(ogImage, {
      font: {
        loadSystemFonts: false,
      },
    });
    const pngData = resvg.render();
    const pngBuffer = pngData.asPng();

    return new Response(pngBuffer, {
      status: 200,
      headers: {
        "Content-Type": "image/png",
      },
    });
  } catch (error) {
    console.error("Resvg wasm not initialized => ", error);
    return new Response("Resvg wasm not initialized", { status: 500 });
  }
}

In local, it work as expect, but when I deploy to Cloudflare pages, but when I access the API, function initWasm keep throw error with message

CompileError: WebAssembly.instantiate(): Wasm code generation disallowed by embedder

Is there anyone know the solution for this ?

@yisibl
Copy link
Member

yisibl commented Mar 3, 2024

Hi @harlan-zw

nuxt-og-image looks like it uses resvg-js and supports Cloudflare, can you help with this?

@yisibl yisibl added the help wanted Extra attention is needed label Mar 3, 2024
@davidtranjs
Copy link
Author

I think the issue is from NextJS's bundler (webpack)
I create another cloudflare worker and workers-og work great.

@yisibl
Copy link
Member

yisibl commented Mar 4, 2024

Webpack is a rabbit hole 🐰

@harlan-zw
Copy link

Nice one, FWIW I previously had just used static strings for the WASM import that get replaced once the build artifact is ready. This prevents bundlers from trying to do something with the WASM imports.

https://github.com/unjs/unwasm was recently released and solves this much better though.

@davidtranjs
Copy link
Author

davidtranjs commented Mar 24, 2024

This issue is not from this library but Cloudflare runtime, root cause is I used fetch to load the wasm file and Cloudflare runtime not allow to run these code because of security.

Solution for this is cloudflare/next-on-pages#704 (comment)

@yisibl
Copy link
Member

yisibl commented Mar 24, 2024

@harlan-zw Thank you for your help.

@dungmidside Thanks for the clarification, it will help other users.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
help wanted Extra attention is needed
Projects
None yet
Development

No branches or pull requests

3 participants