In the browser
Vue and Nuxt
A client-only component that draws the answer after it mounts, in Nuxt 4 or any Vue 3 app.
npm install @morphscreen/webpnpm add @morphscreen/webyarn add @morphscreen/webbun add @morphscreen/webThe core runs in the browser. In Nuxt, a component named *.client.vue renders only there, and onMounted runs after its element exists.
Serve the core
Copy morphscreen.wasm into public/ before each build:
// Copies the core out of the package into public/, where the app serves it
// and loadCore("/morphscreen.wasm") fetches it. Run before each build.
import { copyFileSync, mkdirSync } from "node:fs";
import { createRequire } from "node:module";
const require = createRequire(import.meta.url);
mkdirSync("public", { recursive: true });
copyFileSync(require.resolve("@morphscreen/web/morphscreen.wasm"), "public/morphscreen.wasm");The stylesheet
export default defineNuxtConfig({
css: ["@morphscreen/web/morphscreen.css"],
telemetry: false,
});The answer
<script setup lang="ts">
import { onMounted, ref } from "vue";
import { createAnswer, loadCore } from "@morphscreen/web";
import { SAMPLE } from "../sample";
const el = ref<HTMLElement | null>(null);
onMounted(async () => {
const core = await loadCore("/morphscreen.wasm");
const answer = createAnswer(el.value!, { core });
// Your server's stream goes here; this feeds a saved answer in pieces.
for (let i = 0; i < SAMPLE.length; i += 24) {
answer.push(SAMPLE.slice(i, i + 24));
await new Promise((r) => setTimeout(r, 10));
}
answer.end();
document.body.dataset.done = "yes";
});
</script>
<template>
<div ref="el" />
</template><template>
<main>
<!-- The answer draws in the browser; the page around it renders on the server. -->
<MorphAnswer />
</main>
</template>In a Vue app with Vite but no Nuxt, import the core's address the way the Plain JavaScript page does (@morphscreen/web/morphscreen.wasm?url) instead of copying the file.