# Advanced Usage

## Configuring 3D Payment Based on Country

To enable or disable 3D Payment selectively for different countries, set the `use_three_d` parameter to `false` in the `useCompleteCreditCardPaymentMutation` as provided below:

```js
const [completeCreditCardPayment] = useCompleteCreditCardPaymentMutation();

const response = await completeCreditCardPayment({
  ...data,
  use_three_d: false
}).unwrap();
```

## Removing Experimental or Other Options from Next Config

To remove experimental flags from your `next.config.js` file, use the following code:

```js
const enhancedConfig = withPzConfig(nextConfig);

// ...

delete enhancedConfig.experimental.serverActions;
```

## Customizing Response in Middleware.ts

If you use a custom response such as NextResponse.json(), make sure to set the `pz-override-response` header to `true`, as provided below. Otherwise, you will get a 404 error.

```js
const middleware: NextMiddleware = (
  req: PzNextRequest,
  event: NextFetchEvent
) => {
  if (myCondition) {
    return NextResponse.json({ status: 'ok' }, { headers: { 'pz-override-response': 'true' } });
  }

  return NextResponse.next();
};
```

## Custom Segments

The `[pz]` segment encodes `locale`, `currency`, and `url` by default. You can add custom segments via `pzSegments` in `settings.js` to encode additional values into the URL.

### Configuration

Define custom segments in `settings.js` with a `resolve` function that computes the segment value at request time:

```js
/** @type {import('@akinon/next/types').Settings} */
module.exports = {
  // ...
  usePzSegment: true,
  pzSegments: {
    segments: [
      {
        name: 'segment',
        resolve: (context) => context.req.cookies.get('pz-segment')?.value ?? 'default'
      }
    ]
  }
}
```

Default segments (`locale`, `currency`, `url`) are always included automatically. You only need to define your custom ones.

### Resolve Context

The `resolve` function receives a context object with the following properties:

| Property   | Type             | Description                          |
|------------|------------------|--------------------------------------|
| `req`      | `PzNextRequest`  | The incoming request object (cookies, headers, middlewareParams) |
| `event`    | `NextFetchEvent` | The Next.js fetch event (waitUntil, etc.) |
| `url`      | `NextURL`        | Cloned URL object of the current request |
| `locale`   | `string`         | Resolved locale value                |
| `currency` | `string`         | Resolved currency value              |
| `pathname` | `string`         | Pathname without locale prefix       |

### Reading Segment Values

In server components, use `parsePzParams` to read all segment values (both built-in and custom):

```tsx
import { parsePzParams } from '@akinon/next/utils'
import settings from 'settings'

export default function Page({ params }) {
  const { locale, currency, url, segment } = parsePzParams(params, settings)
  // ...
}
```

In client components, use the `usePzParams` hook:

```tsx
'use client'
import { usePzParams } from '@akinon/next/hooks/use-pz-params'

export default function MyComponent() {
  const { locale, currency, url, segment } = usePzParams()
  // ...
}
```

### Example: Cookie-based Segment

A segment that reads a value from a cookie and falls back to a default:

```js
pzSegments: {
  segments: [
    {
      name: 'segment',
      resolve: (context) => context.req.cookies.get('pz-segment')?.value ?? 'default'
    }
  ]
}
```

This encodes the cookie value into the `[pz]` URL parameter. The resulting URL structure becomes:

```
/tr--TL--<encoded-url>--default/page-path
```

### Migration from Legacy Structure

To migrate a project using the legacy `[commerce]/[locale]/[currency]` directory structure to the new `[pz]` segment:

```bash
npx projectzero codemod --codemod=migrate-segments
```

This codemod will:
- Detect all dynamic segments and merge them into `[pz]/`
- Update `settings.js` with `usePzSegment: true`
- Clean up middleware rewrite blocks
- Update path references in `tsconfig.json`, `next.config.js`, and source files
- Replace `params.locale` / `params.currency` / `params.url` usages with `parsePzParams`

## Enabling Browser Back/Forward Cache (bfcache)

By default, dynamic pages may include `Cache-Control: no-store` headers, which prevents browsers from using the back/forward cache (bfcache). To enable bfcache support, set the `BF_CACHE` environment variable to `true`:

```bash
BF_CACHE=true
```

When enabled, a middleware wrapper overrides the `Cache-Control` header to `private, no-cache, max-age=0, must-revalidate`, allowing the browser to cache pages for instant back/forward navigation while still revalidating content on revisit.
