feat: improve og invite preview #227

Closed
priyanshu_bharti wants to merge 2 commits from priyanshu_bharti/flotilla:feature/improve-og-invite-preview into dev
Contributor

Summary

This PR moves invite link previews to server-side Open Graph generation so invite links unfurl correctly everywhere, not just inside Flotilla.

What changed

  • Added a Node runtime server to serve the built app and handle invite metadata on /join.
  • Added invite-specific OG and Twitter tags based on the invite relay.
  • Added fallback behavior so normal pages keep default metadata.
  • Switched container/runtime startup to the Node server.
  • Added a start script in package.json.
  • Updated README run instructions.

Testing

  • Confirmed /join?r=... returns invite title, description, and image tags.
  • Confirmed /join without relay params returns default platform tags.
  • Verified metadata through crawler-style requests and Flotilla preview backend fetches.
## Summary This PR moves invite link previews to server-side Open Graph generation so invite links unfurl correctly everywhere, not just inside Flotilla. ## What changed - Added a Node runtime server to serve the built app and handle invite metadata on /join. - Added invite-specific OG and Twitter tags based on the invite relay. - Added fallback behavior so normal pages keep default metadata. - Switched container/runtime startup to the Node server. - Added a start script in package.json. - Updated README run instructions. ## Testing - Confirmed /join?r=... returns invite title, description, and image tags. - Confirmed /join without relay params returns default platform tags. - Verified metadata through crawler-style requests and Flotilla preview backend fetches.
hodlbod reviewed 2026-04-17 18:50:54 +00:00
hodlbod left a comment
Owner

I don't love this approach. Some comments:

  • Use a framework to serve static stuff rather than handle all the mimetype/http verb stuff ourselves. Maybe an easy way to do this would be to intercept the default static response. If the response is equal to the html template, we can then check the pathname and update og tags.
  • There's a lot of fragile regex/replacement stuff here. Maybe use a real parser. Parse the html file once and then parameterize the updated html.
  • This server has to work for all routes, not just invite codes (that's just where we need it most). Look at app/util/title.ts. We should cover all those cases, and when the url is parameterized, fetch information from the relay's nip 11 (or from nostr) so we can display it. So for example, /space/meta.spaces.coracle.social/eykoushuda1 should have an og title of something like "Coracle Spaces / Hosting" to match the room name.
  • Related to the above, we need to fetch stuff from nostr. You'll want to use utilities from welshman for this. Don't worry about enabling nip 42 auth, we'll just display stuff we have access to.
I don't love this approach. Some comments: - Use a framework to serve static stuff rather than handle all the mimetype/http verb stuff ourselves. Maybe an easy way to do this would be to intercept the default static response. If the response is equal to the html template, we can then check the pathname and update og tags. - There's a lot of fragile regex/replacement stuff here. Maybe use a real parser. Parse the html file once and then parameterize the updated html. - This server has to work for all routes, not just invite codes (that's just where we need it most). Look at `app/util/title.ts`. We should cover all those cases, and when the url is parameterized, fetch information from the relay's nip 11 (or from nostr) so we can display it. So for example, `/space/meta.spaces.coracle.social/eykoushuda1` should have an og title of something like "Coracle Spaces / Hosting" to match the room name. - Related to the above, we need to fetch stuff from nostr. You'll want to use utilities from welshman for this. Don't worry about enabling nip 42 auth, we'll just display stuff we have access to.
server.js Outdated
@@ -0,0 +21,4 @@
"Flotilla is nostr - for communities.",
url: readMetaContent(indexHtml, "og:url") || "",
image: readMetaContent(indexHtml, "twitter:image") || "/maskable-icon-512x512.png",
}
Owner

Remove the defaults, just assert they're non-null and make sure they exist in the app html

Remove the defaults, just assert they're non-null and make sure they exist in the app html
priyanshu_bharti marked this conversation as resolved
server.js Outdated
@@ -0,0 +44,4 @@
".webmanifest": "application/manifest+json; charset=utf-8",
".woff": "font/woff",
".woff2": "font/woff2",
}
Owner

This seems unnecessary, couldn't we delegate this to a framework? i.e. use hono to serve static files and only do the opengraph stuff if we're falling back to index.

This seems unnecessary, couldn't we delegate this to a framework? i.e. use hono to serve static files and only do the opengraph stuff if we're falling back to index.
priyanshu_bharti marked this conversation as resolved
server.js Outdated
@@ -0,0 +65,4 @@
sendText(res, "ok", "text/plain; charset=utf-8", headOnly)
return
}
Owner

We don't need this

We don't need this
priyanshu_bharti marked this conversation as resolved
priyanshu_bharti marked the pull request as work in progress 2026-04-17 20:38:12 +00:00
priyanshu_bharti marked the pull request as ready for review 2026-04-17 20:45:12 +00:00
priyanshu_bharti marked the pull request as work in progress 2026-04-17 20:47:06 +00:00
priyanshu_bharti added 1 commit 2026-04-17 21:24:26 +00:00
priyanshu_bharti force-pushed feature/improve-og-invite-preview from 88bb278adc to 382056c6ba 2026-04-17 21:24:26 +00:00 Compare
priyanshu_bharti added 1 commit 2026-04-17 21:41:24 +00:00
priyanshu_bharti marked the pull request as ready for review 2026-04-18 20:10:13 +00:00
priyanshu_bharti requested review from hodlbod 2026-04-19 14:48:21 +00:00
hodlbod closed this pull request 2026-04-20 17:52:30 +00:00

Pull request closed

Sign in to join this conversation.