Product
Introducing Enhanced Alert Actions and Triage Functionality
Socket now supports four distinct alert actions instead of the previous two, and alert triaging allows users to override the actions taken for all individual alerts.
@arcteryx/sanity-content
Advanced tools
This package exports methods to fetch content from our Sanity CMS. It is heavily influenced by this article recommended to us from Sanity tech contact. [Type-safe GROQ Queries for Sanity Data with Zod](https://www.simeongriggs.dev/type-safe-groq-queries-f
Readme
This package exports methods to fetch content from our Sanity CMS. It is heavily influenced by this article recommended to us from Sanity tech contact. Type-safe GROQ Queries for Sanity Data with Zod.
import { fetchPage } from @arcteryx/sanity-content
import { createClient } from "@sanity/client";
const sanityClient = createClient({
projectId: "<project id>",
dataset: "development",
useCdn: false, // set to `false` to bypass the edge cache
apiVersion: '2023-05-03',
})
// The `page` object is type-safe. You can expect page to have the typed attributes defined in `pageSchema` of `fragments/page.ts`.
// For example: `page.region`, `page.breadcrumbs.items`, etc.
const page = await fetchPage(sanityClient, {
market: "outdoor", // "sale" for outlet
country: "ca",
language: "en",
slug: "help/womens/sizing",
});
`
// If you need to define an `interface` for the type of the `page` object, you can do something like this:
interface Props {
page: Awaited<ReturnType<typeof fetchPage>>,
}
const MyApp = ({ page }: Props) => {
const breadcrumbs = page.breadcrumbs?.items; // type-safe
}
This repo is organized into 2 folders, documents
and fragments
.
Files in this folder will export "fetch" functions that use a SanityClient
object to retrieve documents from the content lake. Their function signature should generally be as follows:
// DocumentTypeParams would be the interface to describe the expected params that should be passed to the client to satisfy the groq query.
function fetchPage (client: SanityClient, params: DocumentTypeParams)
Files in this folder should be small and concise. They're the building blocks used to compose an entire groq query. In general they correspond to the schema definitions created in the sanity-cms
repo, but they don't need to be. For example, a schema could have the firstName
and lastName
attributes, but our groq fragment could choose to query fullName
by having groq concatenate both attributes.
In these files we utilize zod to do two things: Define the output schema for our query, and make that schema type-safe.
These files must export 2 objects:
schema
in the format of <fragmentName>Schema
. For example: breadcrumbSchema
. This object is the zod
definition. And it in itself can be composed of other schema
fragments.query
in the format of <fragmentName>Query
. For example: breadcrumbsQuery
. This is the partial groq query. And it in itself can be composed of other query
fragments.See breadcrumbs.ts for an example of composition.
Document Fragments
These fragments are used in the fetch functions defined within the documents
folder. So they should also export 3 more items:
filter
in the format of <fragement name>Filter
. For example pageFilter
. This is used in the groq query to filter down or search the specific document.params
in the format of <FragmentName>Params
. For example PageParams
. (Note: capital case). This is a type-safe interface
that specifies the required params that will be passed to SanityClient
to satisfy the groq query.queryParams
validator function. This is to help ensure the params used in sanityClient.fetch
match the schema defined by the interface
above. This function should usually always look like this: export const queryParams = (params: <FragmentName>Params) => params;
. Then the "fetch" function defined in the documents
folder should validate the params like so: sanityClient.fetch(query, queryParams(params))
.See fragments/page.ts and documents/page.ts for an example.
sectionSchema
To accept new types for sections field in sectionSchema
, add the new type in baseSectionListSchema
and not in the sections field itself. This is so that schemas using baseSectionListSchema
like orTab
will be able to accept this new section type.
When constructing a query, you are able to access it directly using the name of the value in a shorthand notation.
export const query = groq`{
name,
content
}`;
If you need to conduct a more indepth query or rename the key, you need to wrap in double quotes.
export const query = groq`{
name,
"contentArray":content
}`;
There are times when your query may not have any data. This will typically return null for your value. To ensure that you return a value, you can use the coalesce function. This is valuable when creating a schema using an array; if there are no items in the array, return an empty array rather than null.
export const query = groq`{
name,
"content": coalesce(content, [])
}`;
There are times when you want the output of your data from Sanity to include optional fields. An example would be the inclusion of a component in certain scenarios. If the component is to be included in the view, you would add it in sanity and expect that key to be present in the response. If the component is not to be included, than that key will be omitted from the response.
Example:
export const query = groq`{
name,
content != null => {
content
}
}`;
In this case, if content exists in the query than it will be retreived and returned in the response.
const response = {name:'', content:{...}}
If there is no content in the query, then it will be omitted from the response
const response = {name:'',}
Another option would be to use the coalesce function and return a default value
export const query = groq`{
name,
"content" : coalesce(content, {})
}`;
If there is no content in the query, then the fallback will be used. This method will also require a more complicated Zod schema since you will need to account for the nested undefined values.
const response = {name:'', content:{}}
However, this approach will produce a type signature that will contain multiple undefined fields. This may require adapting in the front end.
To ensure that a value coming from the Content Lake is strictly equal, you can use the z.literal method.
export const schema = z.object({
type: z.literal("button"),
});
If this schema is called and the type does not equal "button", the validation will fail.
When using Zod data types, it helps to distinguish Zod types against Javascript data types when it's used like this:
z.object()
z.array()
z.string()
But not this:
const { object, array, string } = z;
object()
array()
string()
This repo will automatically publish releases to @arcteryx/sanity-content on npm when there is a merge to main
. We utilize the semantic-release package to handle this for us. It also depends on our commit messages following conventional commits.
FAQs
This package exports methods to fetch content from our Sanity CMS. It is heavily influenced by this article recommended to us from Sanity tech contact. [Type-safe GROQ Queries for Sanity Data with Zod](https://www.simeongriggs.dev/type-safe-groq-queries-f
We found that @arcteryx/sanity-content demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 3 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports four distinct alert actions instead of the previous two, and alert triaging allows users to override the actions taken for all individual alerts.
Security News
Polyfill.io has been serving malware for months via its CDN, after the project's open source maintainer sold the service to a company based in China.
Security News
OpenSSF is warning open source maintainers to stay vigilant against reputation farming on GitHub, where users artificially inflate their status by manipulating interactions on closed issues and PRs.