
Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag storeLooking at your GROQ query examples, the issue is about dynamic attribute access using variables with the @ operator (which refers to the current scope).
Here's what's happening:
Working examples:
"test": override_en_gb - Direct attribute access works"test1": @["override_en_gb"] - Bracket notation with a literal string worksNot working:
"test2": @["override_"+$lang] - String concatenation inside bracket notation doesn't work"test3": @[string("override_"+$lang)] - Even explicit string conversion doesn't workGROQ's bracket notation for attribute access (@[...]) expects a string literal or a direct variable reference, not a computed/concatenated expression. The expression inside the brackets is not evaluated as a dynamic key lookup in the way you might expect from JavaScript.
select() for conditional attribute access*[]{
"test": select(
$lang == "en_gb" => @.override_en_gb,
$lang == "fr" => @.override_fr,
$lang == "de" => @.override_de
)
}This is the most GROQ-native approach - you explicitly handle each language case.
If you're using a JavaScript client, compute the field name before passing it to GROQ:
const lang = "en_gb";
const fieldName = `override_${lang}`;
const query = `*[]{ "test": @[$fieldName] }`;
const result = await client.fetch(query, { fieldName });*[]{ ... }Then in your application code:
const result = await client.fetch(query);
const processed = result.map(doc => ({
...doc,
test: doc[`override_${lang}`]
}));The fundamental limitation is that GROQ doesn't support dynamic string concatenation for property access paths. The bracket notation @[...] is meant for accessing properties with special characters or when the property name is stored in a variable, but that variable must contain the complete property name as a string value - not a concatenated expression.
If you need truly dynamic field access based on runtime values, Option 1 (select()) is your best bet for keeping the logic in GROQ, or Option 2/3 for handling it in your application code.
Sanity is the developer-first content operating system that gives you complete control. Schema-as-code, GROQ queries, and real-time APIs mean no more workarounds or waiting for deployments. Free to start, scale as you grow.
Content operations
Content backend


The only platform powering content operations
By Industry


Tecovas strengthens their customer connections
Build and Share

Grab your gear: The official Sanity swag store
Read Grab your gear: The official Sanity swag store