Mentionwell

Server route

// server/api/blog/[...].get.ts
export default defineEventHandler(async (event) => {
  const config = useRuntimeConfig();
  const path = getRouterParam(event, "_") ?? "";
  const target = `${config.blogotoApiUrl}/api/public/${config.blogotoSiteSlug}/${path}${event.node.req.url?.includes("?") ? "?" + event.node.req.url.split("?")[1] : ""}`;
  return await $fetch(target, {
    headers: { Authorization: `Bearer ${config.blogotoApiKey}` }
  });
});

Composable

// composables/useBlog.ts
export const useBlogList = () => useFetch("/api/blog/posts");
export const useBlogPost = (slug: string) => useFetch(`/api/blog/posts/${slug}`);

Pages

<!-- pages/blog/index.vue -->
<script setup lang="ts">
const { data } = await useBlogList();
</script>
<template>
  <ul><li v-for="post in data?.posts" :key="post.slug">
    <NuxtLink :to="`/blog/${post.slug}`">{{ post.title }}</NuxtLink>
  </li></ul>
</template>
<!-- pages/blog/[slug].vue -->
<script setup lang="ts">
const route = useRoute();
const { data } = await useBlogPost(route.params.slug as string);
</script>
<template>
  <article>
    <h1>{{ data?.post.title }}</h1>
    <div v-html="data?.post.html" />
  </article>
</template>

nuxt.config.ts

export default defineNuxtConfig({
  runtimeConfig: {
    blogotoApiUrl: process.env.MENTIONWELL_API_URL,
    blogotoSiteSlug: process.env.MENTIONWELL_SITE_SLUG,
    blogotoApiKey: process.env.MENTIONWELL_API_KEY
  }
});