Querying single pages
When we are querying a single page instead of a modular page, we do know which information we need exactly for that page and we will need to query it specifically.
Querying
Section titled “Querying”To this end we use another barrel file that determines which single query should be added to the main query:
export const singles = ({ type, language, langParam }) => { let singleToFetch; switch (type) { case "webinars": singleToFetch = `{${webinar({ language, langParam })}}`; break; case "blogs": singleToFetch = `{ ${blogs({ language })}}`; break; ... }}And this is how a single query file looks like:
import { asset, wysiwyg_simple } from "@utilities/groq";import { cybersec_resource } from "@utilities/groq/reference";import wysiwyg from "@utilities/groq/wysiwyg.js";export const security_concepts = ({ language }) => { return ` 'typeName': *[_type == 'cybersecurity_glossary_names'][0]{'title' : security_concepts.${language} }, 'title' : title.${language}, 'hero_description': {${wysiwyg_simple({ name: "hero_description", language })}}, 'description': {${wysiwyg("wysiwyg", language)}}, 'related_resources': { 'title': *[_type == 'global_singles'][0]{'title':security_concepts_related_resources.${language} }, 'resources' : *[_type == 'security_concepts' && _id != ^._id] | order(_createdAt desc)[0...5]{ ${cybersec_resource({ language, isReference: false })} } }, 'cybersec_breadcrumb': *[_type == 'cybersecurity_glossary_names'][0]{ 'text' : cybersecurity_glossary.${language}, 'url': cybersecurity_glossary_url->attributes.slug }, 'security_concepts_breadcrumb': *[_type == 'cybersecurity_glossary_names'][0]{ 'text' : security_concepts.${language}, 'url': security_concepts_url->attributes.slug }, 'share_on': *[_type == 'global_texts'][0]{'text' : share_on.${language} }, 'to_top': *[_type == 'global_texts'][0]{'text' : to_top_text.${language} }, 'socials_texts': { 'email_subject': *[_type == 'global_texts'][0]{'text' : share_email_subject.${language} }, 'email_text': *[_type == 'global_texts'][0]{'text' : share_email_text.${language} }, 'share_text': *[_type == 'global_singles'][0]{'text' : security_share_title.${language} }, }, 'sidebar_titles' : *[_type == 'global_singles'][0]{ 'cybersecurity_sidebar_title_anchors' : cybersecurity_sidebar_title_anchors.${language} , }, 'featured_image': attributes{${asset({ localized: false, name: "featured_image", language })}}`;};So we get specifically the information we need for each single page.
Passing to single page file
Section titled “Passing to single page file”When we have our data, we will pass it on to a single page that will look something like this:
---
const searchParams = Astro.url.searchParams;const isDraft = validatePreviewToken(searchParams.get('preview'));const content = await the_query({ type:'security_concepts', language: lang, slug: `${preSlug}/security-concepts/${slug}` , isDraft});const single = content?.general?.single;if(!content){ return Astro.redirect('/404')}
...
---<Layout payload={{contentSeo : content?.general?.attributes?.settings, seo : content?.general?.siteSettings, language: lang, productSolutionName: content?.general?.product_code, pageTitle: content?.title}}> <section> <div class="f--container"> <div class="f--row">
<!-- CONTENT --> <article class="f--col-7 f--col-desktop-9 f--col-tabletm-12 f--offset-1 f--offset-desktop-0 c--border-b c--border-b--tabletm-none u--pb-10 u--pb-tablets-8 u--pr-15 u--pr-desktop-2"> <HeroD payload={{ language: lang, customClass: 'c--hero-d--eighth', breadcrumb: [ { label: single?.cybersec_breadcrumb?.text, option: 'target_self', slug: single?.cybersec_breadcrumb?.url, }, { label: single?.security_concepts_breadcrumb?.text, option: 'target_self', slug: single?.security_concepts_breadcrumb?.url, }, { label: single?.title, } ], title: single?.title, content: single?.hero_description }} />
{ single?.featured_image?.url && <Asset payload={{ ...single.featured_image, type: "Image", decodingAsync: single.featured_image.decoding, customClass: "c--media-a c--media-a--fifth u--mt-4 u--mb-2", sizes: "(max-width: 580px) 95vw, (max-width: 1024px) 90vw, 75vw", }} /> } { content?.general?.single?.description && <Content payload={{ content : content?.general?.single?.description, customClass : 'c--content-a u--pt-5 u--pt-tablets-4 u--pb-7 u--pb-tablets-5' }}></Content> }
<div class="c--border-a c--hlist-a c--hlist-a--third u--pt-3 u--pb-8"> <p class="c--hlist-a__item f--font-f f--color-f">{single?.share_on.text}</p> <Social01 payload={ socialShare } /> </div> ... </div> </section> <BackTopA payload={{ text: single?.to_top?.text || 'TO top' }} /></Layout>Notice how we send our type and slug here to retrieve the single page we need:
const content = await the_query({ type: "security_concepts", language: lang, slug: `${preSlug}/security-concepts/${slug}`, isDraft,});So each piece of data goes directly from content.general.single into the HTML template.