Skip to content
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

OpenGraph images are not statically generated for dynamic routes #51147

Open
1 task done
Cretezy opened this issue Jun 12, 2023 · 13 comments
Open
1 task done

OpenGraph images are not statically generated for dynamic routes #51147

Cretezy opened this issue Jun 12, 2023 · 13 comments
Labels
area: app App directory (appDir: true) bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. Metadata Related to Next.js' Metadata API.

Comments

@Cretezy
Copy link

Cretezy commented Jun 12, 2023

Verify canary release

  • I verified that the issue exists in the latest Next.js canary release

Provide environment information

Operating System:
      Platform: linux
      Arch: x64
      Version: #1 ZEN SMP PREEMPT_DYNAMIC Sun, 04 Jun 2023 11:52:10 +0000
    Binaries:
      Node: 18.16.0
      npm: 9.5.1
      Yarn: 1.22.10
      pnpm: 8.6.1
    Relevant packages:
      next: 13.4.5-canary.12
      eslint-config-next: 13.4.5
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 5.1.3

Which area(s) of Next.js are affected? (leave empty if unsure)

App directory (appDir: true), Metadata (metadata, generateMetadata, next/head, head.js), Static HTML Export (output: "export")

Link to the code that reproduces this issue or a replay of the bug

https://codesandbox.io/p/sandbox/reverent-feather-2sycr6

To Reproduce

  • Set output: "export" in next.config.js
  • Create dynamic path (a path with param, e.g. app/[id]/page.tsx) which has generateStaticParams
  • Create opengraph-image.tsx for that path
  • Don't set runtime (which defaults to 'auto'/'nodejs')
  • Build Next.js (npm run build)

Describe the Bug

The opengraph-image is not generated for dynamic paths when statically rendering.

In the output, it's marked as λ (Server) server-side renders at runtime for the dynamic paths (e.g. /[id]/opengraph-image), without listing each generated path (which /[id] would have, e.g. /1, /2,).

I can confirm it generates a .html for each path in out, but no opengraph-image is preset.

(It does work if it has no parameter in the path)

Example build output:
image

Expected Behavior

A opengraph-image would be generated for each path returned by generateStaticParams, same as the page.tsx file would.

Which browser are you using? (if relevant)

No response

How are you deploying your application? (if relevant)

Statically rendered

NEXT-1458

@Cretezy Cretezy added the bug Issue was opened via the bug report template. label Jun 12, 2023
@github-actions github-actions bot added area: app App directory (appDir: true) Metadata Related to Next.js' Metadata API. labels Jun 12, 2023
@joeyiny
Copy link

joeyiny commented Jun 29, 2023

Having this issue as well.

@altano
Copy link

altano commented Jul 20, 2023

@huozhi it looks like you fixed this for server rendered dynamic routes in #48704. Any chance you could take a look if the fix is just as easy for output: "export" dynamic routes?

@huozhi huozhi added the linear: next Confirmed issue that is tracked by the Next.js team. label Jul 20, 2023
@chakkun1121
Copy link

You forgot the generateStaticParams function in opengraph-image.tsx. But when I add generateStaticParams function like below, an error has occurred like below.

// opengraph-image.tsx
...
+ export function generateStaticParams() {
+   return [{ id: "1" }, { id: "2" }];
+ }

error

Error: Page "/[id]/opengraph-image" is missing "generateStaticParams()" so it cannot be used with "output: export" config.
    at /project/sandbox/node_modules/next/dist/build/index.js:909:59
    at processTicksAndRejections (node:internal/process/task_queues:96:5)
    at async Span.traceAsyncFn (/project/sandbox/node_modules/next/dist/trace/trace.js:105:20)
    at async Promise.all (index 6)
    at async /project/sandbox/node_modules/next/dist/build/index.js:802:17
    at async Span.traceAsyncFn (/project/sandbox/node_modules/next/dist/trace/trace.js:105:20)
    at async /project/sandbox/node_modules/next/dist/build/index.js:741:124
    at async Span.traceAsyncFn (/project/sandbox/node_modules/next/dist/trace/trace.js:105:20)
    at async build (/project/sandbox/node_modules/next/dist/build/index.js:184:29)
    at async main (/project/sandbox/node_modules/next/dist/bin/next:156:5)
error Command failed with exit code 1.
info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

(I updated all the libraries.)
(I'm Japanese, so please forgive me if my English is strange.)

@altano
Copy link

altano commented Oct 3, 2023

@chakkun1121 yes this is broken. There is no known workaround.

You can’t use export and opengraph images in dynamic routes. It won’t work.

@Cretezy
Copy link
Author

Cretezy commented Oct 11, 2023

I'm getting the same behavior as @chakkun1121 in Next 13.5 now too.

@beeirl
Copy link

beeirl commented Nov 13, 2023

Opengraph Image generation doesn't seem to work with output: "export" being set in next.config.js. Getting a 404 error when trying to access the og image. Using Next 14.0.2. Any ideas for potential workarounds? cc @huozhi

@loganzartman
Copy link

loganzartman commented Nov 13, 2023

In dev mode with output: export, I can't load the opengraph-images even for un-parameterized routes. When I try to visit the generated OG image URL, I get:

Error: Page "/opengraph-image/[[...__metadata_id__]]/route" is missing exported function "generateStaticParams()", which is required with "output: export" config.

Maybe the problem is that Next.js is generating this route /opengraph-image/[[...__metadata_id__]]/route, which obviously won't work with output: export unless it has generateStaticParams(). If there were some way to remove the randomized ID param for the opengraph-image and have this be a non-parameterized route, maybe that would work?

Kind of odd that the images are generated in the build output (for non-parameterized routes), and they work in dev mode if I remove output: export.

@altano
Copy link

altano commented Dec 3, 2023

@loganzartman yes I believe opengraph images ALSO don't work with catch-all routes (whether output:exporting or not). Someone else reported that in #57403 and #57349.

Opengraph images are pretty broken right now. There are no known workarounds for these issues.

@steventhanna
Copy link

I was able to get something working by doing the following:

In my page.js file located: /app/[[...slug]]/page.js

import Logo from '../opengraph-image.png';

export function generateMetadata() {
    return {
        openGraph: {
            images: [Logo.src]
        }
    }
}

I also was not able to get it working just by dropping the file in the tree, after much trial and error I had to manually add this piece.

@loganzartman
Copy link

loganzartman commented Dec 6, 2023

I should point out that you can work around this for dynamic routes too. I created a route handler called [slug]/og.png/route.ts and defined both generateStaticParams and a GET handler that generates an image:

// [slug]/og.png/route.ts

export async function generateStaticParams() {
  // your logic here; this is copied directly from my dynamic route `[slug]/page.tsx`
  return getAllPosts().map(({data: {slug}}) => ({slug}));
}

export async function GET(req: Request, {params}: {params: {slug: string}}) {
  return new ImageResponse(...);
}

example

In output: export mode, this generates image files in the output. Then you can manually link these images as OpenGraph metadata using generateMetadata() in [slug]/page.tsx:

// [slug]/page.tsx

export async function generateStaticParams() {
  // again, duplicated in `[slug]/og.png/route.ts`
  return getAllPosts().map(({data: {slug}}) => ({slug}));
}

export function generateMetadata({params}: Props): Metadata {
  const post = getPostBySlug(params.slug);
  return {
    openGraph: {
      images: `/blog/${params.slug}/og.png`,
    },
  };
}

example

@rusakovic
Copy link

@loganzartman thank you for your solution. Did you work with no output: export, but dynamic? To rebuild OG images?

@altano
Copy link

altano commented Mar 7, 2024

@loganzartman neat idea. that worked perfectly for my site: I was able to switch to output: export and my OG images load instantly now.

It's a shame the built-in OG support is busted but this hack will do. Thanks!

@suyalcinkaya
Copy link

@loganzartman Thanks for the solution ❤️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: app App directory (appDir: true) bug Issue was opened via the bug report template. linear: next Confirmed issue that is tracked by the Next.js team. Metadata Related to Next.js' Metadata API.
Projects
None yet
Development

No branches or pull requests

10 participants