Netlify edge functions - Change meta tags

Hello!

I have some trouble with edge functions, so the question is:

I have my react app already runing with netlify default builder, but i wat to change html meta tags dinamicaly before the html send to client/user, expecificaly og:image to show when people do ctrl + c/v in whatsapp, facebook , X etc…
but i don’t find any solution to get my aplication already builded, change the header and return it to user

i want in every request i call my personal api to get the image i want, change html meta tag og:image and return it to user before the page render in client browser

Hey Daniel, welcome to the Netlify Forums!

I think you’re looking for something like the html-rewriter: GitHub - worker-tools/html-rewriter: WASM-based implementation of Cloudflare's HTML Rewriter for use in Deno, browsers, etc.

import { 
  HTMLRewriter 
} from 'https://ghuc.cc/worker-tools/html-rewriter/index.ts'

export default async (request, context) => {
   const response = await context.next()
   return new HTMLRewriter().on("meta", ...).transform(response)
}

Thanks for the response!

So the context.net() is the html from build folder?
And if i want to change a lot of tags i need to call a lot of HTMLRewriter to every meta tag?
Can you make example for meta tags please?

You can read up on context.next here: Edge Functions API | Netlify Docs

One call to HTMLRewriter#transform should be enough, you can add as many rewrite rules as you want to that. Since og:image a HTML tag like any other, you can edit it just like the html-rewriter docs show.

im trying this, but not working =/

exports.handler = async (_request, context) => {
  const response = await context.next();
  return await new HTMLRewriter()
    .on("head > meta", {
      element(e) {
        // get attributes to read tags
        // not all meta tags have a name and value
        let ogImageProperty = e.getAttribute("property='og:image'");
        ogImageProperty.setAttribute(
          "content='https://treasureboxfiles.s3.us-east-2.amazonaws.com/website/images/a264c129947a2700b4fe-hsshouji_4902370535457.jpg'"
        );
        return ogImageProperty;
      },
    })
    .transform(response);
};

When you figure out how it works, maybe you could update this thread? That would be helpful to others looking to do similar stuff :slight_smile:

im trying, but it’s to confusing, i change to edge-funtions, but not working too =(
can you help?

finally worked, but with some problem, i don’t know how to see logs in netlify, there’s a way to connect it?
And, its a react app with react router dom, and i have routes for product details, but i think netlify can’t see react router changes, because that the edge function call only one time, when the application render

theres a way to get react router dom changes to edge functions?

import { HTMLRewriter } from "https://raw.githubusercontent.com/worker-tools/html-rewriter/master/index.ts";
let figura = {};
const changeMetaTag = async (request, context) => {
  const url = new URL(request.url).origin;
  const params = url.search("product");
  const response = await context.next();

  // the Fetch API returns a Promise
  await fetch(`http://localhost:5000/get-one-product?productID=${params}`)
    .then((response) => response.json())
    .then((data) => (figura = data));

  return await new HTMLRewriter()
    .on("head > meta", new MetaRewriter())
    .transform(response);
};

class MetaRewriter {
  element(element) {
    if (element.getAttribute("property") === "og:image") {
      element.setAttribute("content", figura?.data?.productsImages[0]?.code);
    }
  }
}

export default changeMetaTag;

every time i change the route in react app, the edge function not calling again =/

React Router will handle the routing on client-side. It doesn’t make a new request to the server, so it’s not possible to trigger an Edge Function on client-side route change.

But if all you need is Facebook/WhatsApp preview images, I’m not sure if this would cause any issues.

i want the preview in whatsapp/facebook, twiiter etc, but to make that work i need to change meta tags when the cliente enter in my details page, because in that route i have the product id, but only in react router, and Edge function will handle that id and get the product in my API and change the meta tag, because the react router i can’t make a new request to the sever and change the meta tag =/

i don’t know another solution for that, maybe next js with server side render? i dont know if that work, but i’m very exausted to try that, i’m trying to make this around a month

I think you’ve got the flow incorrect. You need to do something like:

  • In the Edge Function grab the URL
  • Parse the URL and get the details from that (like product ID, project ID, blog slug, etc. - whatever identifier you use for your pages)
  • Make an API call to your database, CMS, or any other tool to fetch the data from there and generate a meta tag based on that.
  • Use that data to append the meta tags in the HTML for that request.

The way you’re currently trying to solve this is not possible using Edge Functions. Your alternatives:

  • Use prerendering
  • OR switch to Next.js