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.

View as Markdown
Terminal
npm install @morphscreen/web
Terminal
pnpm add @morphscreen/web
Terminal
yarn add @morphscreen/web
Terminal
bun add @morphscreen/web

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

copy-wasm.mjs
// 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

nuxt.config.ts
export default defineNuxtConfig({
  css: ["@morphscreen/web/morphscreen.css"],
  telemetry: false,
});

The answer

app/components/MorphAnswer.client.vue
<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>
app/app.vue
<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.