Concatenating first character of fields in Sanity GROQ query

6 replies
Last updated: Jun 28, 2024
Why doesn't this work?
"initials": _firstName_[0]
+ _lastName_[0]
😞
AI Update

I can see the issue! The problem is with how you're trying to concatenate strings in GROQ. You're using _firstName_[0] which is trying to reference a field with underscores wrapping it, but that's not the correct syntax.

In GROQ, you need to use the + operator between string values, and you should reference fields by their actual field names. Here's the correct syntax:

"initials": firstName[0..1] + lastName[0..1]

Or if you want just the first character of each:

"initials": firstName[0] + lastName[0]

Key differences:

  1. Field names: Use firstName and lastName (not _firstName_ and _lastName_) unless your actual field names have underscores
  2. String slicing: [0..1] gets the first character as a string, while [0] also works for single characters
  3. Concatenation: The + operator between the two field references combines them

Full example in a projection:

*[_type == "person"]{
  firstName,
  lastName,
  "initials": firstName[0..1] + lastName[0..1]
}

This would turn someone named "John Doe" into initials "JD".

If your field names actually do have underscores (like first_name), then use those exact names. The important part is removing the extra underscores that were wrapping the field names in your original attempt, and making sure the + operator is positioned correctly between the two values you want to concatenate.

Show original thread
6 replies
Work where? is this a Groq query? What does your schema look like?
*[_type == "author"] {
  name,
  "avatarUrl": select(
    defined(image) => image.asset->url,
    "<https://ui-avatars.com/api/?name=>" + 
    coalesce(
      substr(firstName, 0, 1),
      ""
    ) + 
    coalesce(
      substr(lastName, 0, 1),
      ""
    ) +
    "&background=random"
  )
}
Assuming a groq query and not javasript
likely need to do
firstname.split()[0] + lasname.split()[0]
to turn string into array first.
Yes a groq query. We can do that in JS so I just thought it would be nice and simple here, but instead my projection looks like this:
"initials": array::join(string::split(firstName, "")[0...1], "") + array::join(string::split(lastName, "")[0...1], ""),
This works, but it feels icky.
*[_type=="vendor"] {
  "raw" : string::split(vendorName,""),
  "lowercase" : string::split(lower(vendorName),""),
}{
  "initials" : raw[!(@ in ^.lowercase)]
}

// leads to
initials:[…] 2 items
  0:J
  1:B
Is another approach. A different version of this can be a good way to capture duplicates, comparing a regular array and an array::unique() array and accounting for the difference.

Sanity – Build the way you think, not the way your CMS thinks

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.

Was this answer helpful?