Adding custom objects to GROQ query results and sorting them
Unfortunately, you cannot inject custom objects directly into a GROQ query result and sort them together with your Sanity documents. GROQ parameters (using $ syntax) only support JSON literal values - they can't be used to merge custom objects into query results. The spread operator (...) in GROQ is specifically for field projections in objects, not for array concatenation or manipulation.
Since GROQ can't handle this, you'll need to do the array manipulation in your Remix loader code instead. Here's a clean approach:
// In your Remix loader
export async function loader() {
const query = `*[_type == "resource"] | order(title asc)`;
const sanityResources = await client.fetch(query);
const customResource = {
_type: 'resource',
title: 'Hard-coded Route',
slug: { current: '/your-remix-route' },
// other fields matching your resource structure
};
// Combine and sort
const allResources = [...sanityResources, customResource]
.sort((a, b) => a.title.localeCompare(b.title));
return json({ resources: allResources });
}Alternative approaches to consider:
Create it as an actual Sanity document: Even if it's for a hard-coded route, you could create a resource document in Sanity and just reference the static route in the slug field. This keeps all your sorting logic in GROQ and makes it easier for content editors to manage.
Use a singleton document: If this is a one-off special item, you could create a singleton document in Sanity that represents this resource, giving you full GROQ control.
Handle it in your frontend: If sorting client-side is acceptable, you could fetch resources via GROQ and inject/sort the custom item in your React component.
The JavaScript array manipulation approach isn't the end of the world - it's actually quite common when you need to mix CMS content with application-level data. Just make sure your custom object matches the same shape as your Sanity documents so everything works consistently downstream.
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.