Add store policies pages and consent checkboxes#85
Conversation
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
WalkthroughAdds a Store Policies feature: dynamic policy pages fetched from the Spree API, a reusable PolicyConsent checkbox used in registration and guest checkout to enforce consent, policy links in footers, policy constants, and a server data module to fetch individual policies. Changes
Sequence Diagram(s)sequenceDiagram
participant Browser as Browser
participant Server as Next.js Server
participant Spree as Spree API
Browser->>Server: GET /{country}/{locale}/policies/{slug}
Server-->>Spree: client.policies.get(slug)
Spree-->>Server: Policy data (or error)
Server-->>Browser: Render policy page (200) or notFound()
sequenceDiagram
participant User as Browser (User)
participant UI as Storefront UI (PolicyConsent)
participant Server as Next.js Server
User->>UI: Fill form + toggle PolicyConsent
UI->>UI: Validate local consent state
alt consent checked
User->>Server: Submit registration / initiate payment
Server-->>User: Proceed (registration/payment flow)
else consent missing
UI-->>User: Show policyError, focus `#policy-consent`, block submit
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Possibly related PRs
Poem
🚥 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)
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: 4
🧹 Nitpick comments (2)
src/lib/data/policies.ts (1)
8-8: Use the app alias for this import.Prefer
@/lib/data/utilshere so this module follows the repo’s absolute-import convention.Suggested change
-import { withFallback } from "./utils"; +import { withFallback } from "@/lib/data/utils";As per coding guidelines, "Use absolute imports with
@/alias prefix instead of relative imports."🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/data/policies.ts` at line 8, The import for withFallback in policies.ts currently uses a relative path; update it to the repo's absolute-import alias by replacing the "./utils" import with "@/lib/data/utils" so the file uses the app alias convention and stays consistent with other modules that import the withFallback symbol.src/app/[country]/[locale]/(storefront)/policies/[slug]/page.tsx (1)
14-31: Declare this dynamic route’s rendering mode.This new
[slug]page does not exportgenerateStaticParams()ordynamic, so it misses the repo’s required route config for dynamic pages. If policy content is API-driven,export const dynamic = "force-dynamic"is likely the safer default.Suggested change
+export const dynamic = "force-dynamic"; + export async function generateMetadata({As per coding guidelines, "Use generateStaticParams for static generation of dynamic routes or set dynamic = 'force-dynamic' for dynamic rendering."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`[country]/[locale]/(storefront)/policies/[slug]/page.tsx around lines 14 - 31, The dynamic [slug] route (PolicyPage / generateMetadata) lacks a route rendering mode; either implement export async function generateStaticParams() to statically generate policy pages or explicitly declare export const dynamic = "force-dynamic" to opt into runtime rendering; update the file that defines generateMetadata and default PolicyPage to include one of these exports (prefer export const dynamic = "force-dynamic" if policy content is API-driven) so Next.js knows the route’s rendering strategy.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/`[country]/[locale]/(checkout)/checkout/[id]/page.tsx:
- Around line 222-228: The current logic uses authStatus to remove
REGISTRATION_POLICY_SLUGS from the policies list, which incorrectly assumes
authenticated users have given consent; change the filter in the setPolicies
call to consult the user's stored consent metadata (e.g., customer.consents,
acceptedPolicies, or equivalent) instead of authStatus: include
REGISTRATION_POLICY_SLUGS only when a matching consent record exists for the
policy slug and version/timestamp matches the current policy version, otherwise
keep the policy in the checkout list so the user can re-consent; update the code
around setPolicies, allPolicies, REGISTRATION_POLICY_SLUGS and authStatus to
read and validate the consent record (and fallback to showing the policies when
metadata is missing or outdated).
In `@src/app/`[country]/[locale]/(storefront)/account/register/page.tsx:
- Around line 42-52: The form currently treats policies = [] as "no required
policies" while getPolicies() is still pending or has failed; add an explicit
loading/error flag (e.g., policiesLoading or policiesLoaded and setPolicyError
on rejection) in the useEffect that calls getPolicies(), set
policiesLoading=true before the call, set to false in both then and catch (and
setPolicyError(true) on catch), and update the submit enablement/validation
logic (the code around the submit handler / lines referenced 79-87) to
fail-closed: disable submit or return an error if policiesLoading is true or
policyError is true, and require policyConsent only after policiesLoaded is true
so users cannot submit while required policies are still loading or the request
failed.
In `@src/components/layout/Footer.tsx`:
- Line 3: The import of the non-existent Policy type from "@spree/sdk" causes a
TS error; update the Footer component by removing the invalid "Policy" import
and any "policies" prop typing/usages, or replace it with the correct type if
this prop should reference a different resource (locate the Footer component and
its props, the import line "import type { Policy } from \"@spree/sdk\"", and any
references to "policies" inside Footer) and adjust the prop signature and
internal usage accordingly so the component compiles without the missing type.
In `@src/lib/data/policies.ts`:
- Around line 10-16: The current helpers getPolicies and getPolicy swallow
failures via withFallback, causing critical flows (registration/checkout) to
fail open; introduce strict variants (e.g., getPoliciesStrict and
getPolicyStrict or add a strict boolean param) that directly await
_listPolicies()/_getPolicy(slug) and propagate errors instead of returning
[]/null, keep the existing best-effort getPolicies/getPolicy for non-critical UI
like the footer, and update consent-gating callers to use the strict variants so
API/auth outages do not bypass consent checks.
---
Nitpick comments:
In `@src/app/`[country]/[locale]/(storefront)/policies/[slug]/page.tsx:
- Around line 14-31: The dynamic [slug] route (PolicyPage / generateMetadata)
lacks a route rendering mode; either implement export async function
generateStaticParams() to statically generate policy pages or explicitly declare
export const dynamic = "force-dynamic" to opt into runtime rendering; update the
file that defines generateMetadata and default PolicyPage to include one of
these exports (prefer export const dynamic = "force-dynamic" if policy content
is API-driven) so Next.js knows the route’s rendering strategy.
In `@src/lib/data/policies.ts`:
- Line 8: The import for withFallback in policies.ts currently uses a relative
path; update it to the repo's absolute-import alias by replacing the "./utils"
import with "@/lib/data/utils" so the file uses the app alias convention and
stays consistent with other modules that import the withFallback symbol.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: c73f2553-a959-40ed-b0fd-0ca6c805575b
📒 Files selected for processing (9)
README.mdsrc/app/[country]/[locale]/(checkout)/checkout/[id]/page.tsxsrc/app/[country]/[locale]/(storefront)/account/register/page.tsxsrc/app/[country]/[locale]/(storefront)/layout.tsxsrc/app/[country]/[locale]/(storefront)/policies/[slug]/page.tsxsrc/components/layout/Footer.tsxsrc/components/policy/PolicyConsent.tsxsrc/lib/constants/policies.tssrc/lib/data/policies.ts
src/app/[country]/[locale]/(storefront)/account/register/page.tsx
Outdated
Show resolved
Hide resolved
27c1130 to
14f85e3
Compare
There was a problem hiding this comment.
Actionable comments posted: 2
♻️ Duplicate comments (1)
src/app/[country]/[locale]/(checkout)/checkout/[id]/page.tsx (1)
224-230:⚠️ Potential issue | 🟠 MajorDon’t treat authenticated status as proof of accepted consent.
Line 225 removes checkout consent for all authenticated users, but authentication alone does not prove the user accepted the current required policy/version.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`[country]/[locale]/(checkout)/checkout/[id]/page.tsx around lines 224 - 230, The current code blindly clears required checkout policies when authStatus is true (setPolicies(...) uses authStatus ? [] : ...), which assumes authentication implies consent; instead, update the logic in the setPolicies call to check actual accepted policies for the authenticated user (e.g., a userAcceptedPolicies or acceptedPolicySlugs collection) and only omit policies that the user has already accepted, otherwise include required policies from allPolicies filtered by CHECKOUT_CONSENT_POLICY_SLUGS; if accepted policy data is not available, fall back to presenting the filtered required policies so users can re-consent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/app/`[country]/[locale]/(checkout)/checkout/[id]/page.tsx:
- Around line 192-199: The current Promise.all call swallows failures from
getPoliciesStrict() by converting errors into an empty array which makes
policies.length === 0 and bypasses consent; update the code so
getPoliciesStrict() errors are not silently converted to [] (remove the
.catch(() => [] as Policy[])) and instead let the rejection propagate or map it
to a distinct sentinel (e.g., null or throw) so the surrounding logic in
page.tsx (where policies/policies.length and consent enforcement are checked)
can handle failures explicitly (show an error, block checkout, or display
consent UI) rather than treating an error as “no policies.” Ensure any
downstream code that expects an array is updated to handle the new
error/sentinel case.
In `@src/app/`[country]/[locale]/(checkout)/layout.tsx:
- Around line 57-61: The Link rendering for policy links (the JSX element using
Link with key={policy.id}, href={`${basePath}/policies/${policy.slug}`} and
target="_blank" in layout.tsx) is missing a rel attribute; update that Link to
include rel="noopener noreferrer" so external new-tab links are hardened against
tab-nabbing.
---
Duplicate comments:
In `@src/app/`[country]/[locale]/(checkout)/checkout/[id]/page.tsx:
- Around line 224-230: The current code blindly clears required checkout
policies when authStatus is true (setPolicies(...) uses authStatus ? [] : ...),
which assumes authentication implies consent; instead, update the logic in the
setPolicies call to check actual accepted policies for the authenticated user
(e.g., a userAcceptedPolicies or acceptedPolicySlugs collection) and only omit
policies that the user has already accepted, otherwise include required policies
from allPolicies filtered by CHECKOUT_CONSENT_POLICY_SLUGS; if accepted policy
data is not available, fall back to presenting the filtered required policies so
users can re-consent.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 301839c7-ec96-4bbb-8e38-e66894cfc7cf
📒 Files selected for processing (3)
src/app/[country]/[locale]/(checkout)/checkout/[id]/page.tsxsrc/app/[country]/[locale]/(checkout)/layout.tsxsrc/lib/constants/policies.ts
🚧 Files skipped from review as they are similar to previous changes (1)
- src/lib/constants/policies.ts
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (4)
src/lib/constants/policies.ts (1)
1-12: Consider adding a shared type and deriving CONSENT_POLICIES from POLICY_LINKS.The constants are well-organized. A minor improvement would be to define an explicit type and derive
CONSENT_POLICIESfromPOLICY_LINKSto avoid duplication:interface PolicyLink { name: string; slug: string; } export const POLICY_LINKS: PolicyLink[] = [ { name: "Shipping Policy", slug: "shipping-policy" }, // ... ]; const CONSENT_SLUGS = ["privacy-policy", "terms-of-service"] as const; export const CONSENT_POLICIES = POLICY_LINKS.filter((p) => CONSENT_SLUGS.includes(p.slug as typeof CONSENT_SLUGS[number]) );This keeps consent policies in sync with the main list automatically.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/lib/constants/policies.ts` around lines 1 - 12, Define a shared PolicyLink type and stop duplicating entries by deriving CONSENT_POLICIES from POLICY_LINKS: add a PolicyLink interface/type, annotate POLICY_LINKS as PolicyLink[], create a CONST array of consent slugs (e.g., CONSENT_SLUGS) and set CONSENT_POLICIES = POLICY_LINKS.filter(p => CONSENT_SLUGS.includes(p.slug as typeof CONSENT_SLUGS[number])); update any references to POLICY_LINKS and CONSENT_POLICIES accordingly to use the new types.src/components/policy/PolicyConsent.tsx (1)
32-35: Minor: Separator logic has an edge case for single-item arrays.When
CONSENT_POLICIEShas only one item, the conditions work correctly. However, for exactly two items, the first item (index 0) shows nothing, and the second (index 1, which equalslength - 1) shows " and ". This is correct behavior, but the logic could be clearer:{index > 0 && (index === CONSENT_POLICIES.length - 1 ? " and " : ", ")}This is a minor readability nit—the current code works correctly.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/components/policy/PolicyConsent.tsx` around lines 32 - 35, The separator logic inside the CONSENT_POLICIES.map in PolicyConsent.tsx is split into two conditionals and is slightly harder to read for the two-item case; replace the two separate conditionals that render ", " and " and " (using index and CONSENT_POLICIES.length) with a single conditional that for index > 0 renders (index === CONSENT_POLICIES.length - 1 ? " and " : ", "), keeping the same behavior but improving clarity in the map callback.src/app/[country]/[locale]/(storefront)/policies/[slug]/page.tsx (2)
14-37: AddgenerateStaticParamsor setdynamic = 'force-dynamic'.Per coding guidelines, dynamic routes should either use
generateStaticParamsfor static generation or explicitly setdynamic = 'force-dynamic'for dynamic rendering.Since policies are defined in
POLICY_LINKS, you can statically generate these pages:♻️ Proposed fix
+import { POLICY_LINKS } from "@/lib/constants/policies"; + +export function generateStaticParams() { + return POLICY_LINKS.map((policy) => ({ + slug: policy.slug, + })); +} + export async function generateMetadata({ params, }: PolicyPageProps): Promise<Metadata> {As per coding guidelines: "Use generateStaticParams for static generation of dynamic routes or set dynamic = 'force-dynamic' for dynamic rendering."
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`[country]/[locale]/(storefront)/policies/[slug]/page.tsx around lines 14 - 37, The dynamic route lacks either generateStaticParams or an explicit dynamic = 'force-dynamic' flag; add a generateStaticParams function that returns entries for each policy from POLICY_LINKS (use the same slug shape as PolicyPage params) so pages are statically generated, or alternatively export const dynamic = 'force-dynamic' to force runtime rendering; update the module by adding generateStaticParams (referencing POLICY_LINKS and the PolicyPage/PolicyPageProps slug shape) or the dynamic export accordingly.
42-46: Sanitize HTML content to prevent XSS.Using
dangerouslySetInnerHTMLwithpolicy.body_htmlbypasses React's XSS protection. While policy content is typically admin-controlled, sanitizing the HTML adds defense-in-depth against compromised admin accounts or API responses.Consider using a library like DOMPurify:
🛡️ Proposed fix
+import DOMPurify from "isomorphic-dompurify"; {policy.body_html ? ( <div className="prose prose-gray" - dangerouslySetInnerHTML={{ __html: policy.body_html }} + dangerouslySetInnerHTML={{ __html: DOMPurify.sanitize(policy.body_html) }} />Install the package:
npm install isomorphic-dompurify🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`[country]/[locale]/(storefront)/policies/[slug]/page.tsx around lines 42 - 46, The policy page currently injects policy.body_html via dangerouslySetInnerHTML without sanitization; update the component that renders policy.body_html to sanitize the HTML first (use isomorphic-dompurify / createDOMPurify import) and pass the sanitized string to dangerouslySetInnerHTML (e.g., create a local safeHtml = DOMPurify.sanitize(policy.body_html || '') before rendering). Ensure you import the sanitizer at top of the file, handle null/undefined policy.body_html, and keep the same render path (the div that uses dangerouslySetInnerHTML) but replace the raw value with the sanitized safeHtml.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/components/policy/PolicyConsent.tsx`:
- Around line 36-47: The PolicyConsent component currently builds policy links
with href={`/policies/${policy.slug}`} which omits localized basePath; update
the Link creation inside PolicyConsent (where Link and policy.slug are used) to
prefix the path with the passed-in basePath prop (use basePath + '/policies/' +
policy.slug) and ensure PolicyConsent accepts a basePath prop; then update call
sites (register/page.tsx and checkout/[id]/page.tsx) to pass the basePath prop
into PolicyConsent so localized URLs resolve correctly.
---
Nitpick comments:
In `@src/app/`[country]/[locale]/(storefront)/policies/[slug]/page.tsx:
- Around line 14-37: The dynamic route lacks either generateStaticParams or an
explicit dynamic = 'force-dynamic' flag; add a generateStaticParams function
that returns entries for each policy from POLICY_LINKS (use the same slug shape
as PolicyPage params) so pages are statically generated, or alternatively export
const dynamic = 'force-dynamic' to force runtime rendering; update the module by
adding generateStaticParams (referencing POLICY_LINKS and the
PolicyPage/PolicyPageProps slug shape) or the dynamic export accordingly.
- Around line 42-46: The policy page currently injects policy.body_html via
dangerouslySetInnerHTML without sanitization; update the component that renders
policy.body_html to sanitize the HTML first (use isomorphic-dompurify /
createDOMPurify import) and pass the sanitized string to dangerouslySetInnerHTML
(e.g., create a local safeHtml = DOMPurify.sanitize(policy.body_html || '')
before rendering). Ensure you import the sanitizer at top of the file, handle
null/undefined policy.body_html, and keep the same render path (the div that
uses dangerouslySetInnerHTML) but replace the raw value with the sanitized
safeHtml.
In `@src/components/policy/PolicyConsent.tsx`:
- Around line 32-35: The separator logic inside the CONSENT_POLICIES.map in
PolicyConsent.tsx is split into two conditionals and is slightly harder to read
for the two-item case; replace the two separate conditionals that render ", "
and " and " (using index and CONSENT_POLICIES.length) with a single conditional
that for index > 0 renders (index === CONSENT_POLICIES.length - 1 ? " and " : ",
"), keeping the same behavior but improving clarity in the map callback.
In `@src/lib/constants/policies.ts`:
- Around line 1-12: Define a shared PolicyLink type and stop duplicating entries
by deriving CONSENT_POLICIES from POLICY_LINKS: add a PolicyLink interface/type,
annotate POLICY_LINKS as PolicyLink[], create a CONST array of consent slugs
(e.g., CONSENT_SLUGS) and set CONSENT_POLICIES = POLICY_LINKS.filter(p =>
CONSENT_SLUGS.includes(p.slug as typeof CONSENT_SLUGS[number])); update any
references to POLICY_LINKS and CONSENT_POLICIES accordingly to use the new
types.
🪄 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: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 5736ee50-c977-4b49-8223-5c6c89e49ec9
📒 Files selected for processing (8)
src/app/[country]/[locale]/(checkout)/checkout/[id]/page.tsxsrc/app/[country]/[locale]/(checkout)/layout.tsxsrc/app/[country]/[locale]/(storefront)/account/register/page.tsxsrc/app/[country]/[locale]/(storefront)/layout.tsxsrc/app/[country]/[locale]/(storefront)/policies/[slug]/page.tsxsrc/components/layout/Footer.tsxsrc/components/policy/PolicyConsent.tsxsrc/lib/constants/policies.ts
✅ Files skipped from review due to trivial changes (1)
- src/app/[country]/[locale]/(storefront)/layout.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
- src/app/[country]/[locale]/(checkout)/layout.tsx
- src/components/layout/Footer.tsx
- Add policy detail pages fetched from Spree API (/policies/[slug]) - Add policy consent checkbox on registration (Privacy Policy & Terms of Service) - Add policy consent checkbox on checkout (all policies for guests, excluding registration policies for authenticated users) - Add policies section in footer with dynamic links - Fix footer links to use localized basePath Closes #60 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
When users submit without checking the policy consent checkbox, highlight it with a red border, red label text, and scroll/focus to it. Replace the custom error div in checkout with the shadcn Alert component for consistency. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add getPoliciesStrict() that propagates errors for consent-gating flows - Registration page blocks submit when policies fail to load (fail-closed) - Checkout uses strict fetcher with graceful fallback - Policy page declared as force-dynamic for API-driven content Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Authenticated users accepted terms during registration, so no checkbox is shown at checkout. Guest users see only the Terms of Service checkbox. All policy links are now displayed in the checkout footer. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…config Remove overengineered policy fetching from checkout, registration, and layouts. Policies are now hardcoded in constants — no API calls, no loading states, no error handling for consent. Footer and checkout footer use shared POLICY_LINKS, consent checkbox uses CONSENT_POLICIES. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
… 0.19 getPolicy was removed from @spree/next in 0.19.0. Use getClient() directly via src/lib/data/policies.ts, matching the project's data-fetching pattern. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dc9a6bd to
218c50a
Compare
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/app/[country]/[locale]/(storefront)/policies/[slug]/page.tsx (1)
1-12: Add dynamic rendering configuration.Per coding guidelines, dynamic routes should either use
generateStaticParamsfor static generation or setdynamic = 'force-dynamic'for dynamic rendering. Since policies are admin-managed and may change, dynamic rendering is likely appropriate here.🔧 Suggested fix
import type { Metadata } from "next"; import { notFound } from "next/navigation"; import { getPolicy } from "@/lib/data/policies"; import { getStoreName } from "@/lib/seo"; +export const dynamic = "force-dynamic"; + interface PolicyPageProps {🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/app/`[country]/[locale]/(storefront)/policies/[slug]/page.tsx around lines 1 - 12, This page currently lacks dynamic rendering config; add an explicit export const dynamic = 'force-dynamic' at the top of the module to opt this dynamic route into runtime rendering (since content served by getPolicy can change) and keep existing imports/logic (getPolicy, getStoreName, notFound, PolicyPageProps) unchanged so Next uses dynamic rendering for this policy page.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/app/`[country]/[locale]/(storefront)/policies/[slug]/page.tsx:
- Around line 1-12: This page currently lacks dynamic rendering config; add an
explicit export const dynamic = 'force-dynamic' at the top of the module to opt
this dynamic route into runtime rendering (since content served by getPolicy can
change) and keep existing imports/logic (getPolicy, getStoreName, notFound,
PolicyPageProps) unchanged so Next uses dynamic rendering for this policy page.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 21fa6f49-92c0-44e7-a5ad-a6405ca83a0e
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (11)
README.mdsrc/app/[country]/[locale]/(checkout)/checkout/[id]/page.tsxsrc/app/[country]/[locale]/(checkout)/layout.tsxsrc/app/[country]/[locale]/(storefront)/account/register/page.tsxsrc/app/[country]/[locale]/(storefront)/layout.tsxsrc/app/[country]/[locale]/(storefront)/policies/[slug]/page.tsxsrc/components/layout/Footer.tsxsrc/components/policy/PolicyConsent.tsxsrc/lib/constants/policies.tssrc/lib/data/index.tssrc/lib/data/policies.ts
✅ Files skipped from review due to trivial changes (5)
- src/app/[country]/[locale]/(storefront)/layout.tsx
- src/lib/data/index.ts
- src/lib/constants/policies.ts
- README.md
- src/components/policy/PolicyConsent.tsx
🚧 Files skipped from review as they are similar to previous changes (1)
- src/app/[country]/[locale]/(checkout)/layout.tsx
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Summary
/policies/[slug]) that fetch content from Spree APIPOLICY_LINKS,CONSENT_POLICIES) — no dynamic API fetching for consent/footer@spree/next0.19.0 (getPolicyremoved — usesgetClient().policies.get())Closes #60
Test plan
/us/en/policies/terms-of-service— policy content renders from Spree API/us/en/account/register— consent checkbox shows "I agree to the Privacy Policy and Terms of Service"/us/en/policies/terms-of-service)🤖 Generated with Claude Code