Encountering the "TypeError: fetch failed" error message while attempting to utilize @vercel/og in conjunction with Astro

I've been experimenting with the @vercel/og package in order to set up an API route for generating open graph images.

As I work with an Astro application, I simply followed the vercel example that is framework agnostic:

// api/og.ts
import { ImageResponse } from "@vercel/og";

export const config = {
  runtime: "edge",
};

export default function () {
  return new ImageResponse(
    (
      <div
        style={{
          fontSize: 128,
          background: "white",
          width: "100%",
          height: "100%",
          display: "flex",
          textAlign: "center",
          alignItems: "center",
          justifyContent: "center",
        }}
      >
        Hello world!
      </div>
    ),
    {
      width: 1200,
      height: 600,
    }
  );
}

However, when I run vercel dev and try to access http://localhost:3000/api/og, I encounter a 500 Error stating "This Serverless Function has crashed.". Upon checking the console, I found this error:

TypeError: fetch failed
    at Object.processResponse (evalmachine.<anonymous>:7941:27)
    at evalmachine.<anonymous>:8271:42
    at node:internal/process/task_queues:140:7
    at AsyncResource.runInAsyncScope (node:async_hooks:204:9)
    at AsyncResource.runMicrotask (node:internal/process/task_queues:137:8) {
  cause: Error: not implemented... yet...
      at makeNetworkError (evalmachine.<anonymous>:6735:35) 
      ...
}

Any suggestions on resolving this issue? Thank you in advance

Update

It seems that the problem lies with the import statement itself. For example, using the following code snippet:

import { ImageResponse } from "@vercel/og";

export const config = {
  runtime: "edge",
};

export default function () {
  return new Response("Hello world!");
}

I encounter the same error. However, if I remove the import statement like this:

export const config = {
  runtime: "edge",
};

export default function () {
  return new Response("Hello world!");
}

The function runs without any issues. I suspect it has something to do with my local edge runtime, but I'm not sure how to resolve it yet.

Answer №1

After careful investigation into @vercel/og's source code, I discovered that the problem arises from the fallback font being fetched.

Specifically, in the file

/node-modules/@vercel/og/dist/index.edge.js

It is evident that a custom fallback font is being fetched, leading to the issue at hand. By halting this fetch call, the problem is resolved.

To resolve this, simply comment out or delete the specified lines, and the astro will successfully compile as intended.

// var fallbackFont = fetch(new URL("./noto-sans-v27-latin-regular.ttf", import.meta.url)).then((res) => res.arrayBuffer());
var ImageResponse = class extends Response {
  constructor(element, options = {}) {
    const result = new ReadableStream({
      async start(controller) {
        await initializedYoga;
        await initializedResvg;
        // const fontData = await fallbackFont;
        const fonts = [
          // {
          //   name: "sans serif",
          //   // data: fontData,
          //   weight: 700,
          //   style: "normal"
          // }
        ];
        const result2 = await render(wl, resvg_wasm_exports, options, fonts, element);
        controller.enqueue(result2);
        controller.close();
      }
    });
    super(result, {
      headers: {
        "content-type": "image/png",
        "cache-control": process.env.NODE_ENV === "development" ? "no-cache, no-store" : "public, immutable, no-transform, max-age=31536000",
        ...options.headers
      },
      status: options.status,
      statusText: options.statusText
    });
  }
};

I will report this issue to vercel, as it seems that this package may not be open-source. If it is, kindly inform me.

For now, follow the aforementioned steps to make the necessary changes and utilize npx patch-package to ensure persistence of these modifications, even after reinstalling the package.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

What is the best way to refresh or reload a child component in Angular?

I have a transaction.component.html file that displays the app-deal-partners component. Every time the delete function is triggered, I want to refresh and reload the child component, which is the app-deal-partners component. I need to reload <app-deal- ...

How can I encode and decode a base64 string using AngularJS1 and TypeScript?

I am currently working with Angular1 using TypeScript and I have a question that needs some clarification. Within the environment that I am operating in, is there a method available to encode and decode a string in base64? Despite conducting extensive re ...

Using Promise.all like Promise.allSettled

I am looking to streamline the handling of Promise.allSettled in a more generic way. Currently when using allSettled, it returns a list of both fulfilled and rejected results. I find this cumbersome and do not want to handle it everywhere in my code. My g ...

Transforming API response data into a Typescript object using React mapping

When I make an API call, the response data is structured like this: [ { "code": "AF", "name": "Afghanistan" }, { "code": "AX", "name": "Aland Islands" } ...

Is it possible to have an interface, function, and variable all sharing the same name in a declaration?

Is it possible to have an interface, function, and variable all with the same name? For example, I would like to define the function as follows: declare function someName(...args: any[]); someName('foo'); The interface would look like this: ...

Is there a way to use Regex to strip the Authorization header from the logging output

After a recent discovery, I have come to realize that we are inadvertently logging the Authorization headers in our production log drain. Here is an example of what the output looks like: {"response":{"status":"rejected",&quo ...

Heroku error: unable to locate tsc despite exhaustive troubleshooting efforts

I've been attempting to deploy a basic nodejs app on heroku, but I keep encountering the error mentioned above. Despite trying various solutions provided here, nothing seems to resolve the issue. Here's a summary of what I've attempted so fa ...

Implement FieldResolver in TypeGraphQL for an array of objects

My current dilemma revolves around a specific issue related to the definition of my Cart type, which is structured as follows: @ObjectType() export class Cart { @Field(() => ID) id: string; @Field((_type) => String) ownerId: String ...

Apply a dynamic function to assign a background color to a specific class

Currently, I have a function called getBackground(items) that returns a background color from a JSON file list. Within my application, there is a component that automatically adds a class name (.item-radio-checked) when a user clicks on an item in the list ...

What is the process for importing a function dynamically in a Next.js TypeScript environment?

Currently, I am utilizing a React modal library known as react-st-modal, and I am attempting to bring in a hook named useDialog. Unfortunately, my code is not functioning as expected and appears like this: const Dialog = dynamic<Function>( import(& ...

Issue with Angular data display in template

My Ionic app with Angular is fetching data in the constructor, but I am facing difficulties displaying it in the HTML. Code component receiver: any; constructor( //.... ) { // get receiver data const receiverData = this.activatedRoute.snapsho ...

The 'ngForOf' directive cannot be bound to 'div' element as it is not recognized as a valid property

Encountering an issue with adding an ngFor directive on a div, which is causing a warning and preventing my HTML from rendering properly. I experimented with using *ngFor on various elements like <li>, <tr>, and <span>, but kept getting ...

Unable to retrieve this information within an anonymous function

I am currently working on converting the JSON data received from an API interface into separate arrays containing specific objects. The object type is specified as a variable in the interface. Here is the interface structure: export interface Interface{ ...

I'm curious about why the value of my variable in service.ts keeps changing whenever the page is refreshed?

Below is my Angular service.ts file code. It is used to store the login status. import { Injectable } from '@angular/core'; import { BehaviorSubject } from 'rxjs'; @Injectable({ providedIn: 'root' }) e ...

To ensure successful deployment, it is crucial to provide the supabaseUrl when using NextJs in combination

I'm encountering an issue while trying to deploy my project where I keep receiving an error stating that supabaseUrl is required. The error message can be viewed here. Here is the content of my supabaseClient.js file: import { createClient } from & ...

Storing references to the DOM elements external to the rendering component

Just diving into the world of Electron + Typescript, so please bear with me. Currently, I'm experimenting with what can be achieved within Electron. Issue: My goal is to manipulate DOM elements outside of the renderer. I pass a button as a parameter ...

What is the best way to add JSX to the DOM using React?

Looking to make an addition to my DOM. let parent = document.getElementById("TabContainer"); let settings = <Box id="test"> <GlobalSettings activeTab={"test"}></GlobalSettings> </Box> ...

The React Functional Component undergoes exponential re-renders when there is a change in the array

I'm encountering a problem with one of my functional components. Essentially, it maintains an array of messages in the state; when a new message is received from the server, the state should update by adding that new message to the array. The issue ar ...

How can we enhance intellisense to recognize instance members of an interface when using dynamic indices?

In the midst of developing an angular project, I am currently utilizing an interface to specify a configuration for a module. The design of the interface revolves around mapping names to objects and is relatively straightforward: export interface NamedRou ...

Using @material-ui/core/useScrollTrigger in a Next.js application: a step-by-step guide

I have been researching the Material-UI documentation for useScrollTrigger and attempting to implement it in Next.js to replicate the Elevate App Bar. https://material-ui.com/components/app-bar/#usescrolltrigger-options-trigger import React from "react"; ...