Site Settings API
API reference for the Site Settings document, including the multiple phone numbers feature.
Overview
The Site Settings document is a singleton document in Sanity CMS that contains global site configuration. This API reference covers the GraphQL schema, query examples, and response formats.
Document Type
Type: siteSettings
Document Pattern: Singleton (single instance)
GraphQL Schema
Contact Phone Numbers
The contactPhones field is an array of phone number objects with location-based display.
type ContactPhoneNumber {
number: String!
label: LocalizedString
displayLocation: [String!]!
}
type LocalizedString {
en: String
es: String
ro: String
}
type SiteSettings {
contactPhones: [ContactPhoneNumber!]
contactPhone: String # Legacy field
# ... other fields
}
Fields
contactPhones
Type: ContactPhoneNumber[]
Required: No
Description: Array of phone numbers with labels and display locations
ContactPhoneNumber Object:
number(string, required) - Phone numberlabel(LocalizedString, optional) - Label for the phone numberen(string, optional) - English labeles(string, optional) - Spanish labelro(string, optional) - Romanian label
displayLocation(string[], required) - Array of locations:"contact"and/or"footer"
contactPhone
Type: String
Required: No
Description: Legacy single phone number field (for backward compatibility)
Query Examples
Basic Query - Phone Numbers Only
query GetContactPhones {
SiteSettings(id: "siteSettings") {
contactPhones {
number
label {
en
es
ro
}
displayLocation
}
contactPhone
}
}
Complete Query
query GetSiteSettings {
SiteSettings(id: "siteSettings") {
logo {
asset {
url
}
}
socialLinks {
facebook
twitter
linkedin
instagram
github
}
contactPhones {
number
label {
en
es
ro
}
displayLocation
}
contactPhone
contactEmail
address {
street
city
state
zipCode
country
}
businessHours {
monday
tuesday
wednesday
thursday
friday
saturday
sunday
}
}
}
Filtered Query - Contact Page Phones
query GetContactPagePhones {
SiteSettings(id: "siteSettings") {
contactPhones {
number
label {
en
es
ro
}
displayLocation
}
}
}
Note: Filtering by displayLocation should be done client-side, as GraphQL doesn't support array filtering in queries.
Response Examples
Multiple Phone Numbers
{
"data": {
"SiteSettings": {
"contactPhones": [
{
"number": "+1 234 567 8900",
"label": {
"en": "Main Office",
"es": "Oficina Principal",
"ro": "Biroul Principal"
},
"displayLocation": ["contact", "footer"]
},
{
"number": "+1 234 567 8901",
"label": {
"en": "Sales",
"es": "Ventas",
"ro": "Vânzări"
},
"displayLocation": ["contact"]
},
{
"number": "+1 234 567 8902",
"label": {
"en": "Support",
"es": "Soporte",
"ro": "Suport"
},
"displayLocation": ["footer"]
}
],
"contactPhone": "+1 234 567 8900"
}
}
}
Single Phone Number (Legacy)
{
"data": {
"SiteSettings": {
"contactPhones": null,
"contactPhone": "+1 234 567 8900"
}
}
}
Empty Response
{
"data": {
"SiteSettings": {
"contactPhones": [],
"contactPhone": null
}
}
}
TypeScript Types
Contact Phone Number
interface ContactPhoneNumber {
number: string
label?: {
en?: string
es?: string
ro?: string
}
displayLocation: ('contact' | 'footer')[]
}
Site Settings
interface SiteSettings {
contactPhones?: ContactPhoneNumber[]
contactPhone?: string // Legacy field
contactEmail?: string
// ... other fields
}
Usage Patterns
Get All Contact Page Phones
const siteSettings = await getSiteSettings()
const contactPhones = siteSettings.contactPhones?.filter(
phone => phone.displayLocation.includes('contact')
) || []
Get All Footer Phones
const siteSettings = await getSiteSettings()
const footerPhones = siteSettings.contactPhones?.filter(
phone => phone.displayLocation.includes('footer')
) || []
Fallback to Legacy Field
const siteSettings = await getSiteSettings()
const phones = siteSettings.contactPhones?.length > 0
? siteSettings.contactPhones
: siteSettings.contactPhone
? [{
number: siteSettings.contactPhone,
displayLocation: ['contact', 'footer']
}]
: []
Error Handling
Missing Document
If the Site Settings document doesn't exist:
{
"data": {
"SiteSettings": null
},
"errors": []
}
Invalid Query
If querying a non-existent field:
{
"errors": [
{
"message": "Cannot query field 'invalidField' on type 'SiteSettings'"
}
]
}
Best Practices
1. Always Check for Null
const phones = siteSettings?.contactPhones || []
2. Use Fallback
const phones = getPhonesWithFallback(siteSettings, 'contact')
3. Handle Empty Arrays
if (phones.length === 0) {
// Handle empty state
}
4. Validate Display Locations
const validLocations = ['contact', 'footer']
const phones = siteSettings.contactPhones?.filter(
phone => phone.displayLocation.some(loc => validLocations.includes(loc))
) || []
Migration Notes
Backward Compatibility
- The
contactPhonefield is still available for backward compatibility - New implementations should use
contactPhonesarray - Frontend should check
contactPhonesfirst, then fall back tocontactPhone
Query Migration
Before:
query {
SiteSettings(id: "siteSettings") {
contactPhone
}
}
After:
query {
SiteSettings(id: "siteSettings") {
contactPhones {
number
displayLocation
}
contactPhone # Keep for fallback
}
}
Related Documentation
- Site Settings Schema - Complete schema reference
- Developer Guide - Implementation guide
- Contact Information - Feature overview
- GraphQL API - General GraphQL documentation