Filter posts by tag "internship" in GROQ query

12 replies
Last updated: Jan 22, 2021
Hello, Im trying to understans GROQ and need help understanding what to do next. I want to in post filter all tags with the string internship and let them show when pushing the button on the navbar. This is my code.

🙏
import { useEffect, useState } from "react";
import sanityClient from "../../client.js";
import { Link, useLocation } from "react-router-dom";
import styles from "./allPosts.module.scss";
import { useMousePosition } from "../Animation/useMousePosition"



export default function AllPosts() {
    const [allPostsData, setAllPosts] = useState(null);
    const position = useMousePosition();
    const location = useLocation()
    console.log(location)

    useEffect(() => {
        sanityClient
        .fetch(
            `*[_type == "post" ]{
                title,
                slug,
                tags,
                mainImage{
                    asset ->{
                        _id,
                        url,
                        alt,
                    }
                }
            }`
        )
        .then((data) => setAllPosts(data))
        .catch(console.error)
    }, [])
    return (
        <div className={styles.flex}>
            <div className={styles.landingTitle}>
            {position.x}:{position.y}
                <h1 className={styles.verticalText}>Work</h1>
            </div>

            <div className={styles.wrapper}>
                {allPostsData &&
                    allPostsData.map((post, index) => (
                        <Link to={'/' + post.slug.current} key={post.slug.current}>
                            <span key={index}>
                                <img className={styles.heroImage} 
                                    src={post.mainImage.asset.url} 
                                    caption={post.mainImage.caption} 
                                    alt={post.mainImage.alt}
                                />

                                <h2 className={styles.title}>
                                    {post.title}
                                </h2>
                            </span>
                        </Link>

                    ))}

            </div>
        </div>
    )
}

AI Update

Looking at your code, I can see you want to filter posts by tags containing the string "internship". The key GROQ operator you need is the in operator to check if a value exists in an array.

Here's how to modify your query:

Basic filter for exact match:

sanityClient
  .fetch(
    `*[_type == "post" && "internship" in tags]{
      title,
      slug,
      tags,
      mainImage{
        asset ->{
          _id,
          url,
          alt,
        }
      }
    }`
  )

This uses the in operator which checks if the string "internship" exists anywhere in your tags array.

For a button-triggered filter, add state management:

export default function AllPosts() {
    const [allPostsData, setAllPosts] = useState(null);
    const [showInternships, setShowInternships] = useState(false);
    const position = useMousePosition();
    const location = useLocation();

    useEffect(() => {
        // Build query based on filter state
        const filter = showInternships 
            ? `*[_type == "post" && "internship" in tags]`
            : `*[_type == "post"]`;
        
        sanityClient
            .fetch(
                `${filter}{
                    title,
                    slug,
                    tags,
                    mainImage{
                        asset ->{
                            _id,
                            url,
                            alt,
                        }
                    }
                }`
            )
            .then((data) => setAllPosts(data))
            .catch(console.error);
    }, [showInternships]); // Re-fetch when filter changes

    return (
        <div className={styles.flex}>
            <div className={styles.landingTitle}>
                {position.x}:{position.y}
                <h1 className={styles.verticalText}>Work</h1>
                
                {/* Add filter button */}
                <button onClick={() => setShowInternships(!showInternships)}>
                    {showInternships ? "Show All Posts" : "Show Internships Only"}
                </button>
            </div>

            <div className={styles.wrapper}>
                {allPostsData &&
                    allPostsData.map((post, index) => (
                        <Link to={'/' + post.slug.current} key={post.slug.current}>
                            <span>
                                <img className={styles.heroImage} 
                                    src={post.mainImage.asset.url} 
                                    alt={post.mainImage.alt}
                                />
                                <h2 className={styles.title}>
                                    {post.title}
                                </h2>
                            </span>
                        </Link>
                    ))}
            </div>
        </div>
    );
}

Important notes:

  1. The "internship" in tags syntax checks if the exact string "internship" exists in your tags array
  2. If your tags are objects (like {title: "internship"}), you'd need: "internship" in tags[]->title or similar depending on your schema
  3. The in operator returns true when it finds a match, false if no match, and null if the array contains null values

For partial matching (if you need to match tags that contain "internship" as part of a longer string), you'd use the match operator instead:

`*[_type == "post" && tags match "*internship*"]`

This would match tags like "summer-internship", "internship-2024", etc.

Show original thread
12 replies
Hi
user G
! Let’s keep it in this thread:) also, you might want to use code blocks to make it a bit more readable. https://slack.com/help/articles/202288908-Format-your-messages
user Y
thanx I’ll think of that in future questions 🙂And while you are in the thread, can you plz help me?

I also tried this code in a new component but nothing is working…

useEffect(() => {
    sanityClient.fetch(
        ` *[_type == "post" ] {
            tags,
            'internship' : *[_type == 'internship']{
                title,
                slug,
                mainImage{
                    asset ->{
                        _id,
                        url,
                        alt,
                    }
                }
            }`,
    )
    .then((data) => setInternshipData(data))
    .catch(console.error);
    }, []);

Sure!• Do you have a repo with the code in it? It's easier to help out if I can see your schemas
• You can create a code block by typing three backticks in the message field:

```
Or use this button in the formatting bar
🙂
Should it look like this? because i used the &lt;/&gt; button 😳
Try the one the whole way to the right 🙂
I'm not 100% sure I understand what you're trying to do. I can't see any type named
internship
.
You want to query all your
post
 document, and under each
post
you want to… ?
in the in the post json i have tags, I want to display all tags with “internship”.
{
      name: 'tags',
      type: 'array',
      description: 'add relevent taggs for improve SEO',
      of: [
        {
          type: 'string',
        },
      ],
      options: {
        layout: 'tags',
      },
    },
Thanx for helping me, im really grateful
All posts that has an
internship
 tag?
yes
*[_type == "post" ]{
  title,
  slug,
  tags,
  'internships': *[_type == "post" && 'internship' in tags]{
      _id,
      title,
      slug,
  },
  mainImage{
      asset ->{
          _id,
          url,
          alt,
      }
  }
}
This might work?
Tack
user Y
I’ll try to make it work with the react part 👍

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?