
Getting Started with Contensa: Your Complete Setup Guide
Learn how to set up Contensa CMS in minutes with this step-by-step guide covering installation, configuration, and fetching your first content.
A comprehensive guide to integrating Contensa's powerful GraphQL API into your applications with real-world examples and code snippets.
Alex Rodriguez
Senior Software Engineer

GraphQL has revolutionized how we build and consume APIs. In this guide, we'll explore how to leverage Contensa's GraphQL API to build dynamic, performant applications.
GraphQL offers several advantages over traditional REST APIs:
bashnpm install @apollo/client graphql
typescriptimport { ApolloClient, InMemoryCache, createHttpLink } from '@apollo/client'; import { setContext } from '@apollo/client/link/context'; const httpLink = createHttpLink({ uri: 'https://api.contensa.io/graphql', }); const authLink = setContext((_, { headers }) => { return { headers: { ...headers, authorization: \`Bearer \${process.env.CONTENSA_API_KEY}\`, } }; }); const client = new ApolloClient({ link: authLink.concat(httpLink), cache: new InMemoryCache(), });
typescriptimport { gql, useQuery } from '@apollo/client'; const GET_POSTS = gql` query GetPosts($limit: Int, $offset: Int) { blogPosts(limit: $limit, offset: $offset) { items { id title slug excerpt publishedDate author { name avatar } } total hasMore } } `; function BlogList() { const { loading, error, data } = useQuery(GET_POSTS, { variables: { limit: 10, offset: 0 }, }); if (loading) return <Skeleton />; if (error) return <Error message={error.message} />; return ( <div> {data.blogPosts.items.map(post => ( <BlogCard key={post.id} post={post} /> ))} </div> ); }
graphqlquery GetFilteredPosts( $category: String $tags: [String!] $search: String ) { blogPosts( filter: { category: { eq: $category } tags: { in: $tags } title: { contains: $search } } sort: { publishedDate: DESC } ) { items { id title category tags } } }
Create and update content programmatically:
typescriptconst CREATE_POST = gql` mutation CreatePost($input: BlogPostInput!) { createBlogPost(input: $input) { id title slug publishedDate } } `; const [createPost, { loading }] = useMutation(CREATE_POST); const handleSubmit = async (formData) => { await createPost({ variables: { input: { title: formData.title, content: formData.content, authorId: formData.authorId, } } }); };
typescriptconst cache = new InMemoryCache({ typePolicies: { Query: { fields: { blogPosts: { keyArgs: ['filter', 'sort'], merge(existing, incoming, { args }) { const merged = existing ? existing.items.slice(0) : []; const offset = args?.offset || 0; for (let i = 0; i < incoming.items.length; ++i) { merged[offset + i] = incoming.items[i]; } return { ...incoming, items: merged, }; }, }, }, }, }, });
Use @client directive for local state:
graphqlquery GetPost($id: ID!) { post(id: $id) { id title content isBookmarked @client } }
typescriptconst POST_UPDATED = gql` subscription OnPostUpdated($id: ID!) { postUpdated(id: $id) { id title content updatedAt } } `; function LivePost({ id }) { const { data, loading } = useSubscription(POST_UPDATED, { variables: { id }, }); return <Article post={data?.postUpdated} />; }
Implement robust error handling:
typescriptimport { onError } from '@apollo/client/link/error'; const errorLink = onError(({ graphQLErrors, networkError }) => { if (graphQLErrors) { graphQLErrors.forEach(({ message, locations, path }) => { console.error( \`[GraphQL error]: Message: \${message}, Location: \${locations}, Path: \${path}\` ); }); } if (networkError) { console.error(\`[Network error]: \${networkError}\`); } });
GraphQL provides a powerful, flexible way to interact with your Contensa content. By following these patterns and best practices, you can build fast, maintainable applications.

Learn how to set up Contensa CMS in minutes with this step-by-step guide covering installation, configuration, and fetching your first content.

Discover how to leverage Contensa's AI content generation features to streamline your workflow and create high-quality content faster.

Learn how to manage multilingual content efficiently using Contensa's built-in localization features and reach a global audience.