# ContentNegotiator

> ContentNegotiator supports response format negotiation and application language negotiation.

[API reference](/docs/api/index.md) › [yii](/docs/api/yii/index.md) › [filters](/docs/api/yii/filters/index.md) › ContentNegotiator

| class | `yii\filters\ContentNegotiator` |
| --- | --- |
| Extends | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) » [`yii\base\Behavior`](/docs/api/yii/base/behavior/index.md) » [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| Implements | [`yii\base\BootstrapInterface`](/docs/api/yii/base/bootstrapinterface/index.md), [`yii\base\Configurable`](/docs/api/yii/base/configurable/index.md) |
| Since | 2.0 |
| Source | [`framework/filters/ContentNegotiator.php`](https://github.com/yiisoft/yii2/blob/22.0/framework/filters/ContentNegotiator.php#L91) |

ContentNegotiator supports response format negotiation and application language negotiation.

When the [supported formats](/docs/api/yii/filters/contentnegotiator/index.md#property-formats) property is specified, ContentNegotiator will support response format
negotiation based on the value of the GET parameter [`$formatParam`](/docs/api/yii/filters/contentnegotiator/index.md#property-formatParam) and the `Accept` HTTP header.
If a match is found, the [`Response::$format`](/docs/api/yii/web/response/index.md#property-format) property will be set as the chosen format.
The [`Response::$acceptMimeType`](/docs/api/yii/web/response/index.md#property-acceptMimeType) as well as [`Response::$acceptParams`](/docs/api/yii/web/response/index.md#property-acceptParams) will also be updated accordingly.

When the [supported languages](/docs/api/yii/filters/contentnegotiator/index.md#property-languages) is specified, ContentNegotiator will support application
language negotiation based on the value of the GET parameter [`$languageParam`](/docs/api/yii/filters/contentnegotiator/index.md#property-languageParam) and the `Accept-Language` HTTP header.
If a match is found, the [`Application::$language`](/docs/api/yii/base/application/index.md#property-language) property will be set as the chosen language.

You may use ContentNegotiator as a bootstrapping component as well as an action filter.

The following code shows how you can use ContentNegotiator as a bootstrapping component. Note that in this case,
the content negotiation applies to the whole application.

```
// in application configuration
use yii\web\Response;

return [
    'bootstrap' => [
        [
            'class' => 'yii\filters\ContentNegotiator',
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
                'application/xml' => Response::FORMAT_XML,
            ],
            'languages' => [
                'en',
                'de',
            ],
        ],
    ],
];
```

The following code shows how you can use ContentNegotiator as an action filter in either a controller or a module.
In this case, the content negotiation result only applies to the corresponding controller or module, or even
specific actions if you configure the `only` or `except` property of the filter.

```
use yii\web\Response;

public function behaviors()
{
    return [
        [
            'class' => 'yii\filters\ContentNegotiator',
            'only' => ['view', 'index'],  // in a controller
            // if in a module, use the following IDs for user actions
            // 'only' => ['user/view', 'user/index']
            'formats' => [
                'application/json' => Response::FORMAT_JSON,
            ],
            'languages' => [
                'en',
                'de',
            ],
        ],
    ];
}
```

## Properties

| Property | Type | Description | Defined by |
| --- | --- | --- | --- |
| <span id="property-except"></span>[`$except`](/docs/api/yii/base/actionfilter/index.md#property-except) | `array` | List of action IDs that this filter should not apply to. Default: `[]`. | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) |
| [`$formatParam`](#property-formatParam) | `string` | The name of the GET parameter that specifies the response format. Default: `'_format'`. | `ContentNegotiator` |
| [`$formats`](#property-formats) | `array\|null` | List of supported response formats. Default: `null`. | `ContentNegotiator` |
| [`$languageParam`](#property-languageParam) | `string` | The name of the GET parameter that specifies the [application language](/docs/api/yii/base/application/index.md#property-language). Default: `'_lang'`. | `ContentNegotiator` |
| [`$languages`](#property-languages) | `array\|null` | A list of supported languages. Default: `null`. | `ContentNegotiator` |
| <span id="property-only"></span>[`$only`](/docs/api/yii/base/actionfilter/index.md#property-only) | `array` | List of action IDs that this filter should apply to. Default: `[]`. | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) |
| <span id="property-owner"></span>[`$owner`](/docs/api/yii/base/behavior/index.md#property-owner) | `yii\base\T\|null` | The owner of this behavior Default: `null`. | [`yii\base\Behavior`](/docs/api/yii/base/behavior/index.md) |
| [`$request`](#property-request) | [`yii\web\Request`](/docs/api/yii/web/request/index.md) | The current request. Default: `null`. | `ContentNegotiator` |
| [`$response`](#property-response) | [`yii\web\Response`](/docs/api/yii/web/response/index.md)`\|null` | The response to be sent. Default: `null`. | `ContentNegotiator` |

## Methods

| Method | Description | Defined by |
| --- | --- | --- |
| <span id="method-__construct"></span>[`__construct()`](/docs/api/yii/base/baseobject/index.md#method-__construct) | Constructor. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-__call"></span>[`__call()`](/docs/api/yii/base/baseobject/index.md#method-__call) | Calls the named method which is not a class method. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-__get"></span>[`__get()`](/docs/api/yii/base/baseobject/index.md#method-__get) | Returns the value of an object property. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-__isset"></span>[`__isset()`](/docs/api/yii/base/baseobject/index.md#method-__isset) | Checks if a property is set, i.e. defined and not null. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-__set"></span>[`__set()`](/docs/api/yii/base/baseobject/index.md#method-__set) | Sets value of an object property. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-__unset"></span>[`__unset()`](/docs/api/yii/base/baseobject/index.md#method-__unset) | Sets an object property to null. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-afterAction"></span>[`afterAction()`](/docs/api/yii/base/actionfilter/index.md#method-afterAction) | This method is invoked right after an action is executed. | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) |
| <span id="method-afterFilter"></span>[`afterFilter()`](/docs/api/yii/base/actionfilter/index.md#method-afterFilter) |  | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) |
| <span id="method-attach"></span>[`attach()`](/docs/api/yii/base/actionfilter/index.md#method-attach) | Attaches the behavior object to the component. | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) |
| [`beforeAction()`](#method-beforeAction) | This method is invoked right before an action is to be executed (after all possible filters.) You may override this method to do last-minute preparation for the action. | `ContentNegotiator` |
| <span id="method-beforeFilter"></span>[`beforeFilter()`](/docs/api/yii/base/actionfilter/index.md#method-beforeFilter) |  | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) |
| [`bootstrap()`](#method-bootstrap) | Bootstrap method to be called during application bootstrap stage. | `ContentNegotiator` |
| <span id="method-canGetProperty"></span>[`canGetProperty()`](/docs/api/yii/base/baseobject/index.md#method-canGetProperty) | Returns a value indicating whether a property can be read. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-canSetProperty"></span>[`canSetProperty()`](/docs/api/yii/base/baseobject/index.md#method-canSetProperty) | Returns a value indicating whether a property can be set. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-className"></span>[`className()`](/docs/api/yii/base/baseobject/index.md#method-className) static | Returns the fully qualified name of this class. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-detach"></span>[`detach()`](/docs/api/yii/base/actionfilter/index.md#method-detach) | Detaches the behavior object from the component. | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) |
| <span id="method-events"></span>[`events()`](/docs/api/yii/base/behavior/index.md#method-events) | Declares event handlers for the [`$owner`](/docs/api/yii/base/behavior/index.md#property-owner)'s events. | [`yii\base\Behavior`](/docs/api/yii/base/behavior/index.md) |
| <span id="method-hasMethod"></span>[`hasMethod()`](/docs/api/yii/base/baseobject/index.md#method-hasMethod) | Returns a value indicating whether a method is defined. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-hasProperty"></span>[`hasProperty()`](/docs/api/yii/base/baseobject/index.md#method-hasProperty) | Returns a value indicating whether a property is defined. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| <span id="method-init"></span>[`init()`](/docs/api/yii/base/baseobject/index.md#method-init) | Initializes the object. | [`yii\base\BaseObject`](/docs/api/yii/base/baseobject/index.md) |
| [`negotiate()`](#method-negotiate) | Negotiates the response format and application language. | `ContentNegotiator` |
| <span id="method-getActionId"></span>[`getActionId()`](/docs/api/yii/base/actionfilter/index.md#method-getActionId) protected | Returns an action ID by converting [`Action::$uniqueId`](/docs/api/yii/base/action/index.md#property-uniqueId) into an ID relative to the module. | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) |
| <span id="method-isActive"></span>[`isActive()`](/docs/api/yii/base/actionfilter/index.md#method-isActive) protected | Returns a value indicating whether the filter is active for the given action. | [`yii\base\ActionFilter`](/docs/api/yii/base/actionfilter/index.md) |
| [`isLanguageSupported()`](#method-isLanguageSupported) protected | Returns a value indicating whether the requested language matches the supported language. | `ContentNegotiator` |
| [`negotiateContentType()`](#method-negotiateContentType) protected | Negotiates the response format. | `ContentNegotiator` |
| [`negotiateLanguage()`](#method-negotiateLanguage) protected | Negotiates the application language. | `ContentNegotiator` |

## Property details

### $formatParam <span id="property-formatParam"></span>

```php
public string $formatParam = '_format'
```

The name of the GET parameter that specifies the response format.

Note that if the specified format does not exist in [`$formats`](/docs/api/yii/filters/contentnegotiator/index.md#property-formats), a [`NotAcceptableHttpException`](/docs/api/yii/web/notacceptablehttpexception/index.md)
exception will be thrown.  If the parameter value is empty or if this property is null,
the response format will be determined based on the `Accept` HTTP header only.

### $formats <span id="property-formats"></span>

```php
public array|null $formats = null
```

List of supported response formats.

The keys are MIME types (e.g. `application/json`)
while the values are the corresponding formats (e.g. `html`, `json`) which must be supported
as declared in [`Response::$formatters`](/docs/api/yii/web/response/index.md#property-formatters).

If this property is empty or not set, response format negotiation will be skipped.

### $languageParam <span id="property-languageParam"></span>

```php
public string $languageParam = '_lang'
```

The name of the GET parameter that specifies the [application language](/docs/api/yii/base/application/index.md#property-language).

Note that if the specified language does not match any of [`$languages`](/docs/api/yii/filters/contentnegotiator/index.md#property-languages), the first language in [`$languages`](/docs/api/yii/filters/contentnegotiator/index.md#property-languages)
will be used. If the parameter value is empty or if this property is null,
the application language will be determined based on the `Accept-Language` HTTP header only.

### $languages <span id="property-languages"></span>

```php
public array|null $languages = null
```

A list of supported languages.

The array keys are the supported language variants (e.g. `en-GB`, `en-US`),
while the array values are the corresponding language codes (e.g. `en`, `de`) recognized by the application.

Array keys are not always required. When an array value does not have a key, the matching of the requested language
will be based on a language fallback mechanism. For example, a value of `en` will match `en`, `en_US`, `en-US`, `en-GB`, etc.

If this property is empty or not set, language negotiation will be skipped.

### $request <span id="property-request"></span>

```php
public yii\web\Request $request = null
```

The current request.

If not set, the `request` application component will be used.

### $response <span id="property-response"></span>

```php
public yii\web\Response|null $response = null
```

The response to be sent.

If not set, the `response` application component will be used.

## Method details

### beforeAction() <span id="method-beforeAction"></span>

```php
public function beforeAction(mixed $action): bool
```

This method is invoked right before an action is to be executed (after all possible filters.)
You may override this method to do last-minute preparation for the action.

**Parameters**

| Parameter | Type | Description |
| --- | --- | --- |
| `$action` | `mixed` | The action to be executed. |

**Returns**

`bool`: Whether the action should continue to be executed.

### bootstrap() <span id="method-bootstrap"></span>

```php
public function bootstrap(mixed $app): mixed
```

Bootstrap method to be called during application bootstrap stage.

**Parameters**

| Parameter | Type | Description |
| --- | --- | --- |
| `$app` | `mixed` | The application currently running |

**Returns**

`mixed`

### negotiate() <span id="method-negotiate"></span>

```php
public function negotiate(): mixed
```

Negotiates the response format and application language.

**Returns**

`mixed`

### isLanguageSupported() <span id="method-isLanguageSupported"></span>

```php
protected function isLanguageSupported(string $requested, string $supported): bool
```

Returns a value indicating whether the requested language matches the supported language.

**Parameters**

| Parameter | Type | Description |
| --- | --- | --- |
| `$requested` | `string` | The requested language code |
| `$supported` | `string` | The supported language code |

**Returns**

`bool`: Whether the requested language is supported

### negotiateContentType() <span id="method-negotiateContentType"></span>

```php
protected function negotiateContentType(yii\web\Request $request, yii\web\Response $response): mixed
```

Negotiates the response format.

**Parameters**

| Parameter | Type | Description |
| --- | --- | --- |
| `$request` | [`yii\web\Request`](/docs/api/yii/web/request/index.md) |  |
| `$response` | [`yii\web\Response`](/docs/api/yii/web/response/index.md) |  |

**Returns**

`mixed`

**Throws**

- [`yii\web\BadRequestHttpException`](/docs/api/yii/web/badrequesthttpexception/index.md): if an array received for GET parameter [`$formatParam`](/docs/api/yii/filters/contentnegotiator/index.md#property-formatParam).
- [`yii\web\NotAcceptableHttpException`](/docs/api/yii/web/notacceptablehttpexception/index.md): if none of the requested content types is accepted.

### negotiateLanguage() <span id="method-negotiateLanguage"></span>

```php
protected function negotiateLanguage(yii\web\Request $request): string
```

Negotiates the application language.

**Parameters**

| Parameter | Type | Description |
| --- | --- | --- |
| `$request` | [`yii\web\Request`](/docs/api/yii/web/request/index.md) |  |

**Returns**

`string`: The chosen language