mm-renderer
v0.1.0
Published
My mm renderer library
Downloads
8
Readme
mm-renderer
Render and display web content created with MM Base anywhere — Next, Nuxt, React, Vue, Angular, Svelte, or plain JavaScript.
mm-renderer is a lightweight JavaScript renderer that fetches and renders content from your MM Base project, which is powered by Supabase.
📖 What is MM Base?
MM Base is an admin project that integrates the Mark up manager web markup tool with Supabase as a Backend-as-a-Service (BaaS).
It allows you to easily create, edit, and store static web pages — such as guides, announcements, events, or terms — without requiring developers to rebuild and redeploy.
Key features:
- Create rich content (text, images, videos) with an intuitive web interface
- Manage publish/unpublish state
- Auto-generate meta title, description, and image for link sharing
- Multi-language support
- Data stored in Supabase (with efficient
.webpimage optimization)
🚀 Installation
npm install mm-renderer @supabase/supabase-js
# or
yarn add mm-renderer @supabase/supabase-js
# or
pnpm add mm-renderer @supabase/supabase-js⚙️ Setup
Requirements
- Your Supabase project must have the
mm_poststable andmm_assetsbucket created (see MM Base installation guide). - Have your Supabase URL and anon public API Key ready.
Example
// pages/content/[content].vue
<template>
<div>
<div v-if="pending">Loading…</div>
<div v-else-if="error">Failed to load.</div>
<div
v-else-if="pageData"
v-html="generateHtml(pageData.pages[0].nodes, { t: i18n.t })"></div>
</div>
</template>
<script setup lang="ts">
import { createClient } from "@supabase/supabase-js"
import { generateCss, generateHtml } from "mm-renderer"
// In actual apps, manage them as .env
const client = createClient("https://xyzcompany.supabase.co", "public-anon-key")
const i18n = useI18n()
const { data, pending, error } = await useAsyncData(
"mm-post:2",
async () => {
// ✅ SEO Note:
// Use `.eq("path", route.params.content)` (or a clean URL string) instead of numeric IDs.
// This allows search engines to crawl and index pages by their canonical URL
// rather than opaque IDs, improving SEO discoverability and link sharing
const { data, error } = await client
.from("mm_posts")
.select("*")
.eq("id", 2) // <-- .eq("path", route.params.content)
.single()
if (error) throw error
return data
},
{ lazy: import.meta.client }
)
const pageData = computed(() => {
return data.value?.page_data ? JSON.parse(data.value?.page_data) : undefined
})
onMounted(() => {
if (!data.value?.public) alert("This page is not public")
})
useSeoMeta({
title: () => data.value?.title || "MM Base",
description: () => data.value?.description || "",
ogTitle: () => data.value?.title || "",
ogDescription: () => data.value?.description || "",
ogImage: () => data.value?.image || "",
})
useHead(() => {
const css = pageData.value
? generateCss(pageData.value.pages[0].nodes, pageData.value.widgetGroups)
: ""
return {
style: css ? [{ innerHTML: css, key: "mm-renderer-css" }] : [],
}
})
</script>🌍 Where to use
mm-renderer works in any environment that can run JavaScript in the browser:
- Next.js
- Nuxt
- React
- Vue
- Angular
- Svelte
- Any browser-based project
📦 Why mm-renderer?
- Framework-agnostic: Works with any frontend framework or plain JavaScript.
- No build step required: Can be loaded directly via CDN or npm.
- Seamless Supabase integration: Fetch and render MM Base content directly from your Supabase database.
- Lightweight: Minimal overhead for embedding content.
- Flexible: Perfect for rendering guides, announcements, event pages, terms of service, or any other static content managed in MM Base.
