Skip to content

feat: update page model and integration to support redirects#777

Merged
michnowak merged 1 commit intomainfrom
feat/add-page-redirect-support-776
Mar 12, 2026
Merged

feat: update page model and integration to support redirects#777
michnowak merged 1 commit intomainfrom
feat/add-page-redirect-support-776

Conversation

@michnowak
Copy link
Copy Markdown
Contributor

@michnowak michnowak commented Mar 11, 2026

What does this PR do?

  • Add page-level redirect support to CMS Page model

Related Ticket(s)

Key Changes

  • Added optional redirect field to the CMS Page model in @o2s/framework
    (packages/framework/src/modules/cms/models/page.model.ts)
  • Added redirect to API harmonization Metadata model and page mapper to pass it through from CMS to frontend
  • Added redirect logic in frontend page.tsx — if meta.redirect is present, performs a Next.js redirect to
    /${locale}${meta.redirect}
  • Configured mocked-dxp home page (/) to redirect to /personal (EN), /personlich (DE), /indywidualny (PL) — matching
    dxp-starter-kit behavior

How to test

  1. Switch configs/integrations to use @o2s/integrations.mocked-dxp for cms, articles, and search modules
  2. Run npm install and npm run dev
  3. Navigate to localhost:3000/en — should redirect to localhost:3000/en/personal
  4. Navigate to localhost:3000/pl — should redirect to localhost:3000/pl/indywidualny
  5. Navigate to localhost:3000/de — should redirect to localhost:3000/de/personlich
  6. Verify subpages (e.g. /en/personal/accounts) still work normally without redirect

Media (Loom or gif)

  • N/A

Summary by CodeRabbit

Release Notes

  • New Features
    • Added page redirect functionality with locale-aware support. Pages can now define custom redirects, with the homepage configured to redirect to language-specific destinations for improved user navigation.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Mar 11, 2026

Walkthrough

Implements page-level redirect support across the monorepo by adding an optional redirect field to CMS Page models, propagating it through the API harmonization layer, implementing redirect handling in the frontend page component, and providing locale-specific redirect values in the mocked DXP integration.

Changes

Cohort / File(s) Summary
Changeset Files
.changeset/all-islands-search.md, .changeset/odd-stars-heal.md
Metadata files documenting minor version bumps for @o2s/integrations.mocked-dxp, @o2s/api-harmonization, @o2s/framework, and @o2s/frontend, with feature notes for redirect support.
CMS & API Models
packages/framework/src/modules/cms/models/page.model.ts, apps/api-harmonization/src/modules/page/page.model.ts
Added optional redirect?: string field to Page and Metadata classes to declare page-level redirect targets.
API Harmonization Mapper
apps/api-harmonization/src/modules/page/page.mapper.ts
Passes page.redirect field into the meta.seo.redirect property during page mapping.
Frontend Page Component
apps/frontend/src/app/[locale]/[[...slug]]/page.tsx
Imported redirect from next/navigation and added logic to check meta.redirect after fetching page data; executes locale-prefixed redirect when present.
Mocked DXP Integration
packages/integrations/mocked-dxp/src/modules/cms/mappers/mocks/pages/home.page.ts
Added locale-specific redirect values to home page constants: EN → /personal, DE → /personlich, PL → /indywidualny.

Estimated Code Review Effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Suggested Reviewers

  • marcinkrasowski

Poem

🐰 Hops with delight

A redirect field hops into view,
Pages now know just where to go—
EN, DE, PL all redirect true,
Home pages dance with purpose now,
No empty voids but pathways clear! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding redirect support to the page model and integration.
Description check ✅ Passed The PR description follows the template with all required sections: What does this PR do, Related Ticket, Key Changes, How to test, and Media.
Linked Issues check ✅ Passed All five coding requirements from issue #776 are fully implemented: redirect field added to framework Page class, API harmonization Metadata class, page mapper, frontend page component redirect logic, and mocked-dxp home page configuration.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing page-level redirect support as specified in issue #776; no out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/add-page-redirect-support-776

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions
Copy link
Copy Markdown
Contributor

Coverage Report for packages/configs/vitest-config

Status Category Percentage Covered / Total
🔵 Lines 78.68% 1687 / 2144
🔵 Statements 77.64% 1774 / 2285
🔵 Functions 76% 513 / 675
🔵 Branches 65.46% 1107 / 1691
File Coverage
File Stmts Branches Functions Lines Uncovered Lines
Changed Files
apps/api-harmonization/src/modules/page/page.mapper.ts 63.88% 36.36% 60% 60.6% 93-100, 151-177
packages/integrations/mocked-dxp/src/modules/cms/mappers/mocks/pages/home.page.ts 100% 100% 100% 100%
Generated in workflow #458 for commit 2b11013 by the Vitest Coverage Report Action

@michnowak michnowak marked this pull request as ready for review March 11, 2026 12:37
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
apps/frontend/src/app/[locale]/[[...slug]]/page.tsx (2)

90-101: Note: redirect() is called inside a try-catch block.

Next.js's redirect() works by throwing a special NEXT_REDIRECT error. While the current catch block correctly re-throws unhandled errors (allowing the redirect to work), this pattern is fragile. If future error handling logic is added that doesn't account for the redirect error, it could break silently.

The redirect works correctly now because the error doesn't match the 404/401 checks and gets re-thrown at line 184. However, for clarity and maintainability, consider moving the redirect check before the try block or explicitly handling the redirect error type.

♻️ Alternative: Move data fetch and redirect outside try-catch

One option is to restructure so redirect happens outside the try-catch, though this would require more significant refactoring of the error handling flow.

Alternatively, you could explicitly check for the redirect error in the catch block:

} catch (error) {
    // Allow Next.js redirects to propagate
    if (error && typeof error === 'object' && 'digest' in error && 
        typeof (error as any).digest === 'string' && 
        (error as any).digest.startsWith('NEXT_REDIRECT')) {
        throw error;
    }
    // ... rest of error handling
}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/frontend/src/app/`[locale]/[[...slug]]/page.tsx around lines 90 - 101,
Move the redirect handling out of the try-catch or explicitly allow Next.js
redirect errors to propagate: either perform the meta.redirect check immediately
after calling sdk.modules.getPage and before entering the error-handling catch,
or inside the catch in page.tsx explicitly detect the NEXT_REDIRECT sentinel
(e.g., inspect error.digest starting with 'NEXT_REDIRECT') and re-throw it so
redirect() can work; update the logic around sdk.modules.getPage / meta.redirect
/ redirect() and the surrounding catch block accordingly to ensure redirect
errors are not swallowed.

99-101: Consider validating the redirect path format.

The redirect URL is constructed by concatenating locale and meta.redirect. While the /${locale} prefix constrains redirects to same-origin paths (good for security), the code assumes meta.redirect starts with /. If the CMS provides a value without a leading slash (e.g., personal instead of /personal), the resulting URL would be malformed (e.g., /enpersonal).

Consider adding validation or normalization:

♻️ Proposed validation
         if (meta.redirect) {
-            redirect(`/${locale}${meta.redirect}`);
+            const targetPath = meta.redirect.startsWith('/') ? meta.redirect : `/${meta.redirect}`;
+            redirect(`/${locale}${targetPath}`);
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@apps/frontend/src/app/`[locale]/[[...slug]]/page.tsx around lines 99 - 101,
Normalize and validate meta.redirect before calling redirect: ensure it is a
safe same-origin path by rejecting values that start with '//' or include a
scheme ('http:', 'https:'), then normalize to a single leading slash (e.g., use
'/' + meta.redirect.replace(/^\/+/, '') if not empty) and finally call
redirect(`/${locale}${normalized}`) from the page rendering code (the code that
reads meta.redirect and calls redirect(...)); this prevents malformed
concatenations like `/enpersonal` and blocks protocol-relative or external URLs.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@apps/frontend/src/app/`[locale]/[[...slug]]/page.tsx:
- Around line 90-101: Move the redirect handling out of the try-catch or
explicitly allow Next.js redirect errors to propagate: either perform the
meta.redirect check immediately after calling sdk.modules.getPage and before
entering the error-handling catch, or inside the catch in page.tsx explicitly
detect the NEXT_REDIRECT sentinel (e.g., inspect error.digest starting with
'NEXT_REDIRECT') and re-throw it so redirect() can work; update the logic around
sdk.modules.getPage / meta.redirect / redirect() and the surrounding catch block
accordingly to ensure redirect errors are not swallowed.
- Around line 99-101: Normalize and validate meta.redirect before calling
redirect: ensure it is a safe same-origin path by rejecting values that start
with '//' or include a scheme ('http:', 'https:'), then normalize to a single
leading slash (e.g., use '/' + meta.redirect.replace(/^\/+/, '') if not empty)
and finally call redirect(`/${locale}${normalized}`) from the page rendering
code (the code that reads meta.redirect and calls redirect(...)); this prevents
malformed concatenations like `/enpersonal` and blocks protocol-relative or
external URLs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 098b8c48-f2d5-4461-9df0-5c3c7b9c4848

📥 Commits

Reviewing files that changed from the base of the PR and between b5c9ee9 and 2b11013.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (7)
  • .changeset/all-islands-search.md
  • .changeset/odd-stars-heal.md
  • apps/api-harmonization/src/modules/page/page.mapper.ts
  • apps/api-harmonization/src/modules/page/page.model.ts
  • apps/frontend/src/app/[locale]/[[...slug]]/page.tsx
  • packages/framework/src/modules/cms/models/page.model.ts
  • packages/integrations/mocked-dxp/src/modules/cms/mappers/mocks/pages/home.page.ts

@michnowak michnowak merged commit 0e61431 into main Mar 12, 2026
13 checks passed
@michnowak michnowak deleted the feat/add-page-redirect-support-776 branch March 12, 2026 08:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature] Add page-level redirect support to CMS Page model

2 participants