Skip to content

Commit

Permalink
docs: Consider custom prefixes for open graph images (#1658)
Browse files Browse the repository at this point in the history
Fixes #1657
  • Loading branch information
amannn authored Jan 10, 2025
1 parent 58bf55f commit 8a90489
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -109,9 +109,9 @@ See the [App Router without i18n routing example](/examples#app-router-without-i

### Open Graph images

If you're programmatically generating [Open Graph images](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/opengraph-image), you can apply internationalization by calling functions from `next-intl` in the exported function:
If you're programmatically generating [Open Graph images](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/opengraph-image), you can call functions from `next-intl` in the exported component:

```tsx filename="opengraph-image.tsx"
```tsx filename="app/[locale]/opengraph-image.tsx"
import {ImageResponse} from 'next/og';
import {getTranslations} from 'next-intl/server';

Expand All @@ -121,6 +121,29 @@ export default async function OpenGraphImage({params: {locale}}) {
}
```

Next.js will create a public route based on the segment where `opengraph-image.tsx` is placed, e.g.:

```
http://localhost:3000/en/opengraph-image?f87b2d56cee109c7
```

However, if you're using [i18n routing](/docs/routing) and you've customized the [`localePrefix`](/docs/routing#locale-prefix) setting, this route might not be accessible since Next.js doesn't know about potential rewrites of the middleware.

If this applies to your app, you can adapt your [matcher](/docs/routing/middleware#matcher-config) to bypass requests to the `opengraph-image.tsx` file:

```tsx filename="middleware.ts"
// ...

export const config = {
matcher: [
// Skip all paths that should not be internationalized
'/((?!api|_next|_vercel|.*/opengraph-image|.*\\..*).*)'

// ...
]
};
```

### Manifest

Since [the manifest file](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/manifest) needs to be placed in the root of the `app` folder (outside the `[locale]` dynamic segment), you need to provide a locale explicitly since `next-intl` can't infer it from the pathname:
Expand Down
2 changes: 1 addition & 1 deletion examples/example-app-router-playground/src/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ export default createMiddleware(routing);
export const config = {
matcher: [
// Skip all paths that should not be internationalized
'/((?!_next|.*\\..*).*)',
'/((?!_next|.*/opengraph-image|.*\\..*).*)',

// Necessary for base path to work
'/'
Expand Down
24 changes: 21 additions & 3 deletions examples/example-app-router-playground/tests/main.spec.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import {test as it, expect, BrowserContext} from '@playwright/test';
import {getAlternateLinks, assertLocaleCookieValue} from './utils';
import {BrowserContext, expect, test as it} from '@playwright/test';
import {assertLocaleCookieValue, getAlternateLinks} from './utils';

const describe = it.describe;

Expand Down Expand Up @@ -618,7 +618,10 @@ it('populates metadata', async ({page}) => {
);
});

it('supports opengraph images', async ({page, request}) => {
it('supports opengraph images for the default locale', async ({
page,
request
}) => {
await page.goto('/');
const ogImage = await page
.locator('meta[property="og:image"]')
Expand All @@ -630,6 +633,21 @@ it('supports opengraph images', async ({page, request}) => {
expect(result.ok()).toBe(true);
});

it('supports opengraph images for a locale with a custom prefix', async ({
page,
request
}) => {
await page.goto('/spain');
const ogImage = await page
.locator('meta[property="og:image"]')
.getAttribute('content');
expect(ogImage).toBeTruthy();
const ogImageUrl = new URL(ogImage!);
expect(ogImageUrl.pathname).toBe('/es/opengraph-image');
const result = await request.get(ogImageUrl.pathname);
expect(result.ok()).toBe(true);
});

it('can use async APIs in async components', async ({page}) => {
await page.goto('/');

Expand Down

0 comments on commit 8a90489

Please sign in to comment.