Skip to content

Add Nuxt example application#676

Draft
2chanhaeng wants to merge 6 commits intofedify-dev:mainfrom
2chanhaeng:pr/example-nuxt
Draft

Add Nuxt example application#676
2chanhaeng wants to merge 6 commits intofedify-dev:mainfrom
2chanhaeng:pr/example-nuxt

Conversation

@2chanhaeng
Copy link
Copy Markdown
Contributor

Add Nuxt example application

Depends on #675.

Changes

New example: examples/nuxt/

A comprehensive Nuxt example app demonstrating @fedify/nuxt
integration with ActivityPub federation, following the standard
Fedify example architecture.

Features

  • Federation: Actor dispatcher, inbox listeners (Follow, Undo),
    object dispatcher for Notes, followers collection, NodeInfo, and
    key pair management via server/federation.ts.
  • Vue pages: Home page with post creation, follower/following
    lists, user search, and SSE-powered live updates (pages/index.vue);
    actor profile page (pages/users/[identifier]/index.vue); post
    detail page (pages/users/[identifier]/posts/[id].vue).
  • Server API routes: RESTful endpoints under server/api/ for
    home data, posting, follow/unfollow, search, profile lookup, post
    detail, and SSE events.
  • Static assets: Fedify logo, demo profile image, CSS stylesheet,
    and dark/light theme toggle script in public/.
  • Nuxt config: SSR enabled, @fedify/nuxt module wired with
    federation module path, open host/vite config for tunnel
    compatibility.

@fedify/nuxt bugfix

  • Replaced addTemplate() with addServerTemplate() in
    packages/nuxt/src/mod.ts to ensure the generated federation
    middleware module is available in the Nitro server bundle rather
    than only in the client build output.

Test integration

  • Added Nuxt example to examples/test-examples/mod.ts with
    pnpm build + pnpm start workflow and 30-second ready timeout.

Co-Authored-By: Claude Opus 4.6

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 13, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: ASSERTIVE

Plan: Pro

Run ID: ef0d8d1b-9ee8-40c2-9c39-34c42aef09d1

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands and usage tips.

@issues-auto-labeler issues-auto-labeler bot added component/build Build system and packaging component/federation Federation object related component/integration Web framework integration component/testing Testing utilities (@fedify/testing) labels Apr 13, 2026
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces the @fedify/nuxt package for Nuxt integration, including an example application and support in the fedify init command. Feedback points out a bug in manual request construction within the templates and suggests using h3's toWebRequest utility for better reliability. Additionally, the reviewer recommends correcting a version typo in Node.js types, enabling SSR by default to ensure ActivityPub compatibility, and refactoring the fedify init scaffolding to use the Nuxt module instead of manual middleware.

Comment on lines +1 to +24
import { defineEventHandler } from "h3";
import federation from "../federation";

export default defineEventHandler(async (event) => {
// Construct the full URL from headers
const proto = event.headers.get("x-forwarded-proto") || "http";
const host = event.headers.get("host") || "localhost";
const url = new URL(event.node.req.url || "", `${proto}://${host}`);

const request = new Request(url, {
method: event.node.req.method,
headers: event.node.req.headers as Record<string, string>,
body: ["GET", "HEAD", "DELETE"].includes(event.node.req.method)
? undefined
: undefined,
});

const response = await federation.fetch(request, {
contextData: undefined,
});

if (response.status === 404) return; // Let Nuxt handle 404
return response;
});
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The manual construction of the Request object has a bug where the body is always undefined (lines 13-15), which will break incoming ActivityPub activities (POST requests). Additionally, manual URL reconstruction is error-prone. It is highly recommended to use h3's toWebRequest(event) utility, which correctly handles headers, methods, and bodies across different runtimes and ensures the host/port are preserved correctly.

import { defineEventHandler, toWebRequest } from "h3";
import federation from "../federation";

export default defineEventHandler(async (event) => {
  const request = toWebRequest(event);
  const response = await federation.fetch(request, {
    contextData: undefined,
  });

  if (response.status === 404) return; // Let Nuxt handle 404
  return response;
});
References
  1. When reconstructing a URL from a request object, prefer using methods that preserve the host and port (like the Host header) to ensure functionality like federation signature verification remains intact.

devDependencies: {
...defaultDevDependencies,
"typescript": deps["npm:typescript"],
"@types/node": deps["npm:@types/node@25"],
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

The key npm:@types/node@25 appears to be a typo and is likely missing from packages/init/src/json/deps.json. Node.js version 25 is not yet released. This should probably refer to a current version like @types/node@22 or simply @types/node as defined in the dependencies catalog.

      "@types/node": deps["npm:@types/node"],

@@ -0,0 +1,5 @@
// https://nuxt.com/docs/api/configuration/nuxt-config
export default defineNuxtConfig({
ssr: false,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Setting ssr: false (Single Page Application mode) is generally inappropriate for federated applications. ActivityPub requires the server to respond with JSON-LD to actors, often on the same routes that serve HTML to browsers. Disabling SSR can complicate content negotiation and discovery. It is better to default to ssr: true, as seen in the example application.

  ssr: true,

Comment on lines +24 to +29
"nuxt.config.ts": await readTemplate("nuxt/nuxt.config.ts"),
"server/federation.ts": await readTemplate("nuxt/server/federation.ts"),
"server/logging.ts": await readTemplate("nuxt/server/logging.ts"),
"server/middleware/federation.ts": await readTemplate(
"nuxt/server/middleware/federation.ts",
),
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The fedify init setup for Nuxt is currently inconsistent. It adds @fedify/nuxt to the dependencies but then manually sets up a Nitro middleware in server/middleware/federation.ts. It would be much cleaner and more idiomatic to enable the @fedify/nuxt module in the nuxt.config.ts template and remove the manual middleware file. This avoids redundancy and leverages the module's built-in features like deferred 406 handling.

@codecov
Copy link
Copy Markdown

codecov bot commented Apr 13, 2026

Codecov Report

❌ Patch coverage is 40.83333% with 71 lines in your changes missing coverage. Please review.
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
packages/init/src/webframeworks/nuxt.ts 15.27% 61 Missing ⚠️
packages/init/src/test/port.ts 0.00% 10 Missing ⚠️
Files with missing lines Coverage Δ
packages/init/src/const.ts 100.00% <100.00%> (ø)
packages/init/src/webframeworks/mod.ts 100.00% <100.00%> (ø)
packages/nuxt/src/runtime/server/logic.ts 100.00% <100.00%> (ø)
packages/init/src/test/port.ts 9.60% <0.00%> (-0.84%) ⬇️
packages/init/src/webframeworks/nuxt.ts 15.27% <15.27%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/build Build system and packaging component/federation Federation object related component/integration Web framework integration component/testing Testing utilities (@fedify/testing)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant