- Published on
How to query strapi v4 via graphql for unpublished content
It wasn't entirely obvious from the docs as to how to get these queries to work, so here are some crib notes.
Get published data
By default, Strapi will return your published data:
query {
articles() {
data {
id
attributes{
publishedAt
}
}
}
}
Get unpublished data
In Strapi, there is a an enum value you can pass to a graphql query publicationState
which has two possible values 'LIVE' and 'PREVIEW'. So if you wanted to get all the unpublished articles in Strapi you would do this:
query {
articles(publicationState: PREVIEW) {
data {
id
attributes{
publishedAt
}
}
}
}
Get all published and unpublished data
Here is the graphql you want to query something in strapi and get both published and unpublished content you can batch up the queries like this
query checkArticleBySlug($slug: String!) {
liveArticles: articles(
filters: { Slug: { eq: $slug } }
publicationState: LIVE
) {
data {
id
attributes {
publishedAt
}
}
}
previewArticles: articles(
filters: { Slug: { eq: $slug } }
publicationState: PREVIEW
) {
data {
id
attributes {
publishedAt
}
}
}
}
Note that unpublished data has a null value for publishedAt.
Querying graphql from Nextjs 13 app directory
And here is the code i've used in a project to create a unique slug for submission to Strapi. The slug field can be automatically created when using the admin interface in strapi, but when using the API you need to ensure it's unique. The best way i've found to do this is to query the server and then use recursion to keep generating new random slugs and checking they are available before submitting them. Here's the code:
// create the slug. If it already exists, append a random string to the end and try again
// gradually increase the length of the random string until a unique slug is found
async function createSlug(
title: string,
length = 0
): Promise<string> {
// slugify the title
const baseSlug = slugify(title, { lower: true });
// Generate a random string and append it to the base slug if not the first attempt
const slug =
length === 0 ? baseSlug : baseSlug + generateRandomString(length);
// If the slug is unique, return it
if (await isSlugUnique(slug)) {
return slug;
}
// If the slug is not unique, increase the length for the next recursive call
const increasedLength = length + 1;
// Do 6 recursive calls and throw an error if still not unique
if (increasedLength > 6) {
throw new Error("Could not create a unique slug");
}
// Recursively call createSlug with increased length
return createSlug(title, increasedLength);
}
async function isSlugUnique(slug: string) {
// check if the slug exists in strapi
const { data, error } = await getClient().query<GetArticleBySlugQuery>({
query: GetArticleBySlugDocument,
variables: { slug },
});
if (error) {
throw new Error(error.message);
}
if (data.articles && data.articles.data.length === 0) {
return true;
}
return false;
}
function generateRandomString(length: number): string {
const characters =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
let randomString = "";
for (let i = 0; i < length; i++) {
const randomIndex = Math.floor(Math.random() * characters.length);
randomString += characters.charAt(randomIndex);
}
return randomString;
}
Read more about using gql and codegen here: https://www.heavyengineer.com/blog/graphql-apollo-typescript-nextjs-codegen-strapi