-
Notifications
You must be signed in to change notification settings - Fork 993
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds dynamic og:image generation using middleware and plain components #10075
Conversation
…t to build all the meta tags in one go
…support * 'main' of github.com:redwoodjs/redwood: (30 commits) fix(scenario): Make sure to cleanup even if test fails (#10112) Update babel monorepo to v7.24.0 (#10090) Update storybook monorepo to v7.6.17 (#10089) Update dependency @apollo/client to v3.9.5 (#10087) fix(serve): Allow periods in most paths (#10114) feat(rsc-streaming): Integrating RSC builds with Streaming and Client side hydration (#10031) chore(style): getDefaultViteConfig source format (#10111) chore(refactor): vite - extract default vite config (#10110) chore(comment): cli index FIXME comment about ugly big red box RSC: rscBuildAnalyze: Start at web/src/ (#10109) RSC: ensureProcessDirWeb() (#10108) RSC: Extract webpack shims into their own file (#10107) RSC: Remove completed TODO comment RSC: Babel react plugin not needed for analyze phase (#10106) RSC: runFeServer: wrap RSC code with `if (rscEnabled)` (#10105) RSC: Update comments, naming etc based on Danny's input (#10104) RSC: Rename to buildRscClientAndServer (#10103) RSC: Rename to rscBuildForServer, and tweak some comments (#10102) SSR: Extract buildForStreamingServer function (#10099) chore(unit-tests): Silence middleware error logging (#10097) ...
One enhancement I can think of to:
would be to optionally request (or return)
as well. Maybe be able to deconstruct |
Most of the time, the dimensions for the image are specific to the provider -- Twitter dimensions are different from Facebook which are different from LinkedIn, etc. If there is just one:
dimension then the image may not be tailored for the provider that will unfurl it. Perhaps there is a default for ogProps, but maybe can wrap some dimensions in a provider when returning |
Yeah I was wondering about those size differences, but then I checked out GitHub to see what they do (since their stuff seems to render nicely everywhere) and they just have a single But, that's what I'm seeing when I look at the source in my browser. It's possible that GitHub's servers actually recognize a real Twitter unfurl bot request and generate different |
Closing as superceded by #10441 |
This PR adds Danny & Rob's Conference Hackathon project, now with 75% less hacks!
You can now create a custom og:image for any page in your site as just another regular component alongside your page:
Here's a very barebones example showing you can query for data, access query string parameters, and any route parameters that were present in the Router:
og:images are just URLs, and the URL is the same as the page you're viewing, plus
.png
on the end (other image types are possible). The one exception is for the homepage, since there is no filename to append.png
to:The idea being that every page can have its own unique og:image, and there's no special directory structure you need to create or anything, just add an image-like extension to a regular JSX component and voilà.
The actual generation of the image happens inside middleware, by playwright rendering your component as a real page and then snapshotting it. Images are currently generated on the fly whenever the URL is hit, but we should be able to cache them, or maybe even write them out to the filesystem so that your web server serves them as regular static content (not implemented in this PR).
How to use in your app
See this gist for the
entry.server.jsx
config in your app. We're talking about potentially adding therenderOgImage()
middleware function to Redwood itself, and then you just import and add to yourmiddleware()
function if you want to use it. We also have a stubbedrenderExtension()
which will register any extension and let you render stuff like.json
or.rss
or whatever else you want. This is a big feature we hadn't yet stolen from Rails—UNTIL NOW!To get the URL to your og:image, use the new
useOgImage()
hook:Which creates all of the og:image tags for you:
useOgImage()
takes several options:extension
to render (defaults topng
)width
of the generated imageheight
of the generated imageThe general consensus (and Facebook docs) say that an og:image should be 1200x630 so that's currently the default if no width/height is passed. GitHub (on this very page, in fact) sets theirs to 1200x600.
If you don't want to automatically add the props, you can destructure out everything individually and set them yourself:
Non-breaking Changes
We modified the
App.tsx
template to accept possible children, and render them if present. This lets the og:image handler inject your component into the Document tree, without including the entire Router, but still style your og:image component using whatever you used to style the rest of your app (Tailwind, perhaps?)We also modified the
useLocation()
hook to now return everything that the URL API returns. Previously it only returned three attributes of the url (pathname, search, hash), now it returns everything available to a call tonew URL()
(origin, href, searchParams, etc.).TODO
App.tsx
in fixturesuseOgImageUrl()
hook (basicallyuseLocation().href
+.png
).png.tsx
files get built (vite)renderExtension()
yarn rw setup
command to installDecide
renderOgImage()
middleware (new Redwood package?)