Fix Open Graph / Twitter image metadata for landing & guides and add tests#2428
Conversation
Deploying packrat-guides with
|
| Latest commit: |
c627e35
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://8327ab15.packrat-guides-6gq.pages.dev |
| Branch Preview URL: | https://codex-fix-open-graph-images.packrat-guides-6gq.pages.dev |
|
Warning Rate limit exceeded
You’ve run out of usage credits. Purchase more in the billing tab. ⌛ How to resolve this issue?After the wait time has elapsed, a review can be triggered using the We recommend that you space out your commits to avoid hitting the rate limit. 🚦 How do rate limits work?CodeRabbit enforces hourly rate limits for each developer per organization. Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout. Please see our FAQ for further information. ℹ️ Review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Run ID: 📒 Files selected for processing (4)
WalkthroughThis PR extracts inline metadata definitions from layout files into separate metadata modules for both guides and landing apps. Each app gains a metadata.ts module that centralizes SEO, Open Graph, and Twitter card configuration, with layout files now re-exporting this shared metadata. Tests verify correct Open Graph and Twitter image URL construction. ChangesMetadata Extraction
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Suggested labels
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Tip 💬 Introducing Slack Agent: The best way for teams to turn conversations into code.Slack Agent is built on CodeRabbit's deep understanding of your code, so your team can collaborate across the entire SDLC without losing context.
Built for teams:
One agent for your entire SDLC. Right inside Slack. Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@apps/guides/app/layout.metadata.test.ts`:
- Around line 2-3: Replace the relative imports in this test with the TS path
aliases: change the import of siteConfig (currently from '../lib/config') to
import from 'guides-app/lib/config' and change the import of guidesMetadata
(currently exported as guidesMetadata from './metadata') to import from
'guides-app/app/metadata' or the appropriate alias that maps to the metadata
file; update the import statements to use those 'guides-app/*' aliases so the
test imports siteConfig and guidesMetadata (metadata) via the project alias
policy.
In `@apps/guides/app/layout.tsx`:
- Line 8: Replace the relative import of metadata in layout.tsx with the app
alias: update the import statement that currently imports guidesMetadata from
'./metadata' to use 'guides-app/metadata' instead (i.e., import { guidesMetadata
} from 'guides-app/metadata';) so it conforms to the project's import-path
standard.
In `@apps/guides/app/metadata.ts`:
- Line 2: Replace the relative intra-app import in metadata.ts with the
repository path alias: change the import of siteConfig from '../lib/config' to
use the guides-app alias (import { siteConfig } from 'guides-app/lib/config') so
metadata.ts follows the guides-app/* import contract.
In `@apps/landing/app/layout.metadata.test.ts`:
- Around line 2-3: Replace the relative imports in the test so they use the
landing-app path alias: change the import of siteConfig (currently from
'../config/site') to import from 'landing-app/config/site' and change the import
of landingMetadata as metadata (currently from './metadata') to import from
'landing-app/metadata'; update the import statements that reference siteConfig
and landingMetadata to use those alias paths so the test follows the project's
path-alias guideline.
In `@apps/landing/app/layout.tsx`:
- Line 7: The import in layout.tsx currently pulls landingMetadata from a
relative path; update the import to use the landing-app alias so it reads from
"landing-app/metadata" instead of "./metadata". Locate the import statement that
references landingMetadata and replace the module specifier with the aliased
path to comply with the project's import guideline.
In `@apps/landing/app/metadata.ts`:
- Line 2: The import in metadata.ts uses a relative path; replace the relative
import of siteConfig with the landing-app path alias so it reads from the
aliased module (import siteConfig from "landing-app/config/site" or the
equivalent named export), ensuring you reference the same exported symbol
siteConfig and update any named/default import form to match the original export
in config/site.ts.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro
Run ID: 78f01911-2d14-4467-958a-7aa4ba9ff336
📒 Files selected for processing (6)
apps/guides/app/layout.metadata.test.tsapps/guides/app/layout.tsxapps/guides/app/metadata.tsapps/landing/app/layout.metadata.test.tsapps/landing/app/layout.tsxapps/landing/app/metadata.ts
| import { siteConfig } from '../lib/config'; | ||
| import { guidesMetadata as metadata } from './metadata'; |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Use guides-app/* aliases in this test file.
Lines [2-3] use relative imports into the guides app; update both to guides-app/* aliases to stay aligned with the TS import policy.
As per coding guidelines **/*.{ts,tsx}: "Use path alias guides-app/* to reference files in apps/guides/*".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/guides/app/layout.metadata.test.ts` around lines 2 - 3, Replace the
relative imports in this test with the TS path aliases: change the import of
siteConfig (currently from '../lib/config') to import from
'guides-app/lib/config' and change the import of guidesMetadata (currently
exported as guidesMetadata from './metadata') to import from
'guides-app/app/metadata' or the appropriate alias that maps to the metadata
file; update the import statements to use those 'guides-app/*' aliases so the
test imports siteConfig and guidesMetadata (metadata) via the project alias
policy.
| @@ -0,0 +1,51 @@ | |||
| import type { Metadata } from 'next'; | |||
| import { siteConfig } from '../lib/config'; | |||
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Use the guides-app/* alias for intra-app imports.
Line [2] uses a relative import into apps/guides/*; switch it to the guides-app/* alias to match the repository import contract.
As per coding guidelines **/*.{ts,tsx}: "Use path alias guides-app/* to reference files in apps/guides/*".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/guides/app/metadata.ts` at line 2, Replace the relative intra-app import
in metadata.ts with the repository path alias: change the import of siteConfig
from '../lib/config' to use the guides-app alias (import { siteConfig } from
'guides-app/lib/config') so metadata.ts follows the guides-app/* import
contract.
| import { siteConfig } from '../config/site'; | ||
| import { landingMetadata as metadata } from './metadata'; |
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Replace relative test imports with landing-app/* aliases.
Lines [2-3] should use the landing app path alias instead of relative imports.
As per coding guidelines **/*.{ts,tsx}: "Use path alias landing-app/* to reference files in apps/landing/*".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/landing/app/layout.metadata.test.ts` around lines 2 - 3, Replace the
relative imports in the test so they use the landing-app path alias: change the
import of siteConfig (currently from '../config/site') to import from
'landing-app/config/site' and change the import of landingMetadata as metadata
(currently from './metadata') to import from 'landing-app/metadata'; update the
import statements that reference siteConfig and landingMetadata to use those
alias paths so the test follows the project's path-alias guideline.
| @@ -0,0 +1,43 @@ | |||
| import type { Metadata } from 'next'; | |||
| import { siteConfig } from '../config/site'; | |||
There was a problem hiding this comment.
🛠️ Refactor suggestion | 🟠 Major | ⚡ Quick win
Switch to landing-app/* alias for siteConfig import.
Line [2] should use the landing app alias instead of a relative path to comply with the import boundary rule.
As per coding guidelines **/*.{ts,tsx}: "Use path alias landing-app/* to reference files in apps/landing/*".
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@apps/landing/app/metadata.ts` at line 2, The import in metadata.ts uses a
relative path; replace the relative import of siteConfig with the landing-app
path alias so it reads from the aliased module (import siteConfig from
"landing-app/config/site" or the equivalent named export), ensuring you
reference the same exported symbol siteConfig and update any named/default
import form to match the original export in config/site.ts.
Deploying packrat-landing with
|
| Latest commit: |
c627e35
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://3350147c.packrat-landing.pages.dev |
| Branch Preview URL: | https://codex-fix-open-graph-images.packrat-landing.pages.dev |
There was a problem hiding this comment.
Pull request overview
This PR extracts root metadata for the landing and guides Next.js apps, adds explicit Open Graph/Twitter image metadata, and adds regression tests for those metadata objects.
Changes:
- Added
metadata.tsmodules for landing and guides. - Updated layouts to re-export those metadata objects.
- Added Vitest tests asserting OG/Twitter image entries.
Reviewed changes
Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
apps/landing/app/metadata.ts |
Adds landing metadata with explicit OG/Twitter images. |
apps/landing/app/layout.tsx |
Re-exports extracted landing metadata. |
apps/landing/app/layout.metadata.test.ts |
Tests landing metadata image fields. |
apps/guides/app/metadata.ts |
Adds guides metadata with explicit OG/Twitter images. |
apps/guides/app/layout.tsx |
Re-exports extracted guides metadata. |
apps/guides/app/layout.metadata.test.ts |
Tests guides metadata image fields. |
Comments suppressed due to low confidence (3)
apps/landing/app/metadata.ts:35
- This Twitter image uses the same
og-image.jpgURL, but that asset is not present in the landing app; the app already defines a generatedapp/twitter-image.tsxroute instead. The explicit Twitter metadata should reference a URL that the static export actually serves.
images: [new URL(siteConfig.ogImage, siteConfig.url).toString()],
apps/landing/app/layout.metadata.test.ts:18
- This test only inspects the exported metadata object, but the app also has
app/opengraph-image.tsxandapp/twitter-image.tsx; Next.js gives file-based metadata routes precedence when resolving the actual tags. Rendering/resolving the metadata output would catch whether the deployed OG/Twitter tags use the intended absolute URLs, while this assertion can pass even if production metadata is overridden.
expect(metadata.openGraph?.images).toEqual([
{
url: expectedImageUrl,
width: 1200,
height: 630,
alt: siteConfig.name,
},
]);
expect(metadata.twitter?.images).toEqual([expectedImageUrl]);
apps/guides/app/layout.metadata.test.ts:18
- This test only inspects the exported metadata object, but the app also has
app/opengraph-image.tsxandapp/twitter-image.tsx; Next.js gives file-based metadata routes precedence when resolving the actual tags. Rendering/resolving the metadata output would catch whether the deployed OG/Twitter tags use the intended absolute URLs, while this assertion can pass even if production metadata is overridden.
expect(metadata.openGraph?.images).toEqual([
{
url: expectedImageUrl,
width: 1200,
height: 630,
alt: 'PackRat Guides | Hiking & Outdoor Adventures',
},
]);
expect(metadata.twitter?.images).toEqual([expectedImageUrl]);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| describe('landing metadata', () => { | ||
| it('includes absolute Open Graph and Twitter image URLs', () => { |
| describe('guides metadata', () => { | ||
| it('includes absolute Open Graph and Twitter image URLs', () => { |
| images: [ | ||
| { | ||
| url: new URL(siteConfig.ogImage, siteConfig.url).toString(), |
| images: [ | ||
| { | ||
| url: new URL('/opengraph-image', siteConfig.url).toString(), |
Resolve conflicts in apps/guides/app/layout.tsx and apps/landing/app/layout.tsx by adopting development's lib/metadata.ts location while preserving this PR's absolute-URL improvements (using Next metadata image routes /opengraph-image.png and /twitter-image.png as canonical OG/Twitter URLs via new URL(...)). - Drop redundant app/metadata.ts files (dev moved canonical to lib/metadata.ts) - Update lib/metadata.ts in both guides + landing with absolute image URLs - Update layout.metadata.test.ts imports to point at lib/metadata
The guides + landing vitest configs scope tests to __tests__/**, so the layout.metadata.test.ts files added under app/ were silently skipped.
Deploying with
|
| Status | Name | Latest Commit | Preview URL | Updated (UTC) |
|---|---|---|---|---|
| ✅ Deployment successful! View logs |
packrat-admin | c627e35 | Commit Preview URL Branch Preview URL |
May 16 2026, 10:29 PM |
|
Rebased onto current Conflicts resolved:
Additional fix: moved this PR's Verification (locally, in worktree):
The earlier Cloudflare Pages failures were on the pre-rebase state which referenced Push: |
…(after #2363/#2428 landed) Conflicts: - packages/api/src/routes/trips/index.ts: dev added inline LocationSchema/CreateTripRequestSchema/UpdateTripRequestSchema; this PR already imports the equivalents from @packrat/schemas/trips. Kept HEAD (the extracted-schemas import + body refs to CreateTripBodySchema/UpdateTripBodySchema). - bun.lock: regenerated via bun install. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
#2428 landed) Conflicts: - apps/expo/features/packs/hooks/usePackOwnershipCheck.ts: HEAD used new single-object obs({store,id}) signature with .peek() (non-reactive); dev rewrote to use$(() => !!obs(packsStore, id).get()) for reactivity. Blended: kept dev's reactive use$ pattern, applied HEAD's single-object obs call form. Post-merge fixes (dev added new files that violated max-params=1): - apps/expo/atoms/atomWithSecureStorage.web.ts: refactor to {key, initialValue} to match native sibling. - apps/expo/features/packs/utils/uploadImage.web.ts: refactor uploadImage/getPresignedUrl/urlToBlob to single-object params; align with native sibling signature. - apps/expo/lib/utils/ImageCacheManager.web.ts: refactor cacheRemoteImage and cacheLocalTempImage to single-object params, matching native ImageCacheManager.ts. - scripts/lint/no-owned-max-params.ts: add /playwright/ to EXCLUDED_PATH_PARTS (parity with /test/ and /__tests__/; playwright fixtures are test code with signatures dictated by Playwright). Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Motivation
Description
apps/landing/app/metadata.tsandapps/guides/app/metadata.tsand added explicitopenGraph.imagesandtwitter.imagesentries usingnew URL(..., siteConfig.url).toString().apps/landing/app/layout.tsxandapps/guides/app/layout.tsxto re-export the new metadata objects viaexport const metadata = ....apps/landing/app/layout.metadata.test.tsandapps/guides/app/layout.metadata.test.tsto assert that OG and Twitter image URLs are present and absolute.Testing
bunx vitest run apps/landing/app/layout.metadata.test.ts apps/guides/app/layout.metadata.test.ts, and both tests passed (2 passed).bunx biome check --write ...to auto-fix import ordering and thenbunx biome check --no-errors-on-unmatched ..., and lint checks passed.Codex Task
Summary by CodeRabbit
Tests
Refactor