LinkedIn Social Connection - "locale" Claim is an Object Instead of a String
While the Open ID Connect (OIDC) specs state the "locale" claim as a string:
LinkedIn returns an object as a value for that attribute, and Auth0 also takes it as an object in the normalized user profile.
This document proposes a solution to pass a flattened "locale" attribute in the token using Actions.
- LinkedIn Social Connection
- "locale" claim
{
"sub": "linkedin|Gxxxxx",
"given_name": "<First Name>",
"family_name": "<Last Name>",
"nickname": "<Nickname>",
"name": "<Full Name>",
...
"locale": {
"country": "ES",
"language": "es"
},
"updated_at": "2025-07-02T15:31:58.178Z",
"iss": "https://<domain>.auth0.com/",
"aud": "<aud>",
"iat": 1751470394,
"exp": 1751506394,
"sid": "<sid>",
...
}
{ "created_at": "2025-07-01T23:40:19.372Z", "family_name": "<Last Name>", "given_name": "<First Name>", "identities": [ { "provider": "linkedin", "user_id": "Gxxxxxxx", "connection": "linkedin", "isSocial": true } ], "locale": { "country": "ES", "language": "es" }, "name": "<Full Name>", "nickname": "<Nickname>", ... "sub": "xxxz", "updated_at": "2025-07-02T15:55:57.034Z", "user_id": "linkedin|Gxxxxxxx", "last_ip": "<IP Address>", "last_login": "2025-07-02T15:55:57.033Z", "logins_count": 9, "blocked_for": [], "guardian_authenticators": [], "passkeys": []}/*** Flatten the locale scope if it's not a string*/exports.onExecutePostLogin = async (event, api) => { const { locale } = event.user; if (typeof locale === "object") { // linkedin sets the locale as an object like this: // "locale": { // "country": "US", // "language": "en" //},
// flatten the locale: api.idToken.setCustomClaim( "locale", `${locale.language}-${locale.country}` ); }};
See Create custom claims for more details on setting custom claims with Actions.