Learn how to build your own JustCMS integration for any framework using AI assistance. Create custom integrations in minutes with step-by-step guidance.
Using artificial intelligence, you can quickly generate a complete integration guide for any framework you want to use with JustCMS. This process is straightforward and takes just a few minutes. The AI will create detailed setup instructions tailored to your specific framework, making it easy to get started right away.
With our specially crafted prompt, you'll be able to:
Generate framework-specific integration instructions
Get step-by-step setup guidelines
Start using JustCMS with your preferred framework immediately
Follow along with the instructions below to create your own custom integration guide.
To create your own JustCMS integration, you can use our pre-made prompt with any AI model that understands code.
Make sure to review the generated code and adjust it according to your specific needs. The AI-generated integration will give you a solid foundation that you can build upon.
You will be given integration (compasable) and readme.md file for integration JustCMS with Nuxtjs.
You need to use best practise to write the whole integration for YOUR_FRAMEWORK.
Create code and give a detailed instruction how to integrate JustCMS with YOUR_FRAMEWORK.
Composable:
import { useRuntimeConfig } from 'nuxt/app';
/**
* Categories
*/
export interface Category {
name: string
slug: string
}
export interface CategoriesResponse {
categories: Category[]
}
/**
* Image types
*/
export interface ImageVariant {
url: string
width: number
height: number
filename: string
}
export interface Image {
alt: string
variants: ImageVariant[]
}
/**
* Pages
*/
export interface PageSummary {
title: string
subtitle: string
coverImage: Image | null
slug: string
categories: Category[]
createdAt: string
updatedAt: string
}
export interface PagesResponse {
items: PageSummary[]
total: number
}
/**
* Content Blocks for a single page
*/
export interface HeaderBlock {
type: 'header'
styles: string[]
header: string
subheader: string | null
size: string
}
export interface ListBlock {
type: 'list'
styles: string[]
options: {
title: string
subtitle?: string | null
}[]
}
export interface EmbedBlock {
type: 'embed'
styles: string[]
url: string
}
export interface ImageBlock {
type: 'image'
styles: string[]
images: {
alt: string
variants: ImageVariant[]
}[]
}
export interface CodeBlock {
type: 'code'
styles: string[]
code: string
}
export interface TextBlock {
type: 'text'
styles: string[]
text: string
}
export interface CtaBlock {
type: 'cta'
styles: string[]
text: string
url: string
description?: string | null
}
export interface CustomBlock {
type: 'custom'
styles: string[]
blockId: string
[key: string]: any
}
export type ContentBlock =
| HeaderBlock
| ListBlock
| EmbedBlock
| ImageBlock
| CodeBlock
| TextBlock
| CtaBlock
| CustomBlock
export interface PageDetail {
title: string
subtitle: string
meta: {
title: string
description: string
}
coverImage: Image | null
slug: string
categories: Category[]
content: ContentBlock[]
createdAt: string
updatedAt: string
}
/**
* Menus
*/
export interface MenuItem {
title: string
subtitle?: string
icon: string
url: string
styles: string[]
children: MenuItem[]
}
export interface Menu {
id: string
name: string
items: MenuItem[]
}
export interface PageFilters {
category: {
slug: string
}
}
/**
* Composable: useJustCMS
*
* Provides methods for fetching JustCMS data:
* - getCategories()
* - getPages()
* - getPageBySlug()
* - getMenuById()
*
* The API token and project ID are taken either from the runtime config (config.public.justCmsToken and config.public.justCmsProject)
* or from the optional parameters.
*/
export function useJustCms(apiToken?: string, projectIdParam?: string) {
const config = useRuntimeConfig()
const token = apiToken || config.public.justCmsToken
const projectId = projectIdParam || config.public.justCmsProject
if (!token) {
throw new Error('JustCMS API token is required')
}
if (!projectId) {
throw new Error('JustCMS project ID is required')
}
// Base URL without the project segment.
const BASE_URL = 'https://api.justcms.co/public'
/**
* Helper: Makes a GET request to a JustCMS endpoint.
* @param endpoint The endpoint (e.g. 'pages' or 'menus/main')
* @param queryParams Optional query parameters.
*
* The full URL is constructed as: ${BASE_URL}/${projectId}/${endpoint}
* If no endpoint is provided, the URL points to ${BASE_URL}/${projectId}.
*/
const get = async <T>(
endpoint: string = '',
queryParams?: Record<string, any>
): Promise<T> => {
// Construct the full URL using the projectId from config.
const url = new URL(${BASE_URL}/${projectId}${endpoint ? '/' + endpoint : ''})
if (queryParams) {
Object.entries(queryParams).forEach(([key, value]) => {
if (value !== undefined && value !== null) {
url.searchParams.append(key, String(value))
}
})
}
const response = await fetch(url.toString(), {
headers: {
Authorization: Bearer ${token}
}
})
if (!response.ok) {
const errorText = await response.text()
throw new Error(JustCMS API error ${response.status}: ${errorText})
}
return response.json()
}
/**
* Retrieves all categories.
*/
const getCategories = async (): Promise<Category[]> => {
const data = await get<CategoriesResponse>() // Calls ${BASE_URL}/${projectId}
return data.categories
}
/**
* Retrieves pages with optional filtering and pagination.
* @param params.filterCategorySlug Filter pages by a specific category slug.
* @param params.start Pagination start index.
* @param params.offset Number of items to return.
*/
const getPages = async (params?: {
filters?: PageFilters
start?: number
offset?: number
}): Promise<PagesResponse> => {
const query: Record<string, any> = {}
if (params?.filters?.category?.slug) {
query['filter.category.slug'] = params.filters.category.slug
}
if (params?.start !== undefined) {
query['start'] = params.start
}
if (params?.offset !== undefined) {
query['offset'] = params.offset
}
return get<PagesResponse>('pages', query)
}
/**
* Retrieves a single page by its slug.
* @param slug The page slug.
* @param version (Optional) If provided, adds the v query parameter (e.g. 'draft').
*/
const getPageBySlug = async (
slug: string,
version?: string
): Promise<PageDetail> => {
const query: Record<string, any> = {}
if (version) {
query['v'] = version
}
return get<PageDetail>(pages/${slug}, query)
}
/**
* Retrieves a single menu by its ID.
* @param id The menu ID.
*/
const getMenuById = async (id: string): Promise<Menu> => {
return get<Menu>(menus/${id})
}
const isBlockHasStyle = (block: any, style: string) => {
if (block.styles.map((s: string) => s.toLowerCase()).includes(style.toLowerCase())) {
return true;
}
return false;
};
const getLargeImageVariant = (image: Image) => {
return image.variants[1];
};
const getFirstImage = (block: any) => {
return block.images[0];
};
const hasCategory = (page: PageDetail, categorySlug: string) => {
return page.categories.map((category) => category.slug).includes(categorySlug);
};
return {
getCategories,
getPages,
getPageBySlug,
getMenuById,
isBlockHasStyle,
getLargeImageVariant,
getFirstImage,
hasCategory
}
}
Readme:
## Installation
1. **Add the Composable:**
Copy the [composables/useJustCMS.ts](./composables/useJustCMS.ts) file into your project's composables directory.
2. **Install Dependencies:**
Make sure your project is set up for TypeScript and uses NuxtJS. If not, follow the [NuxtJS installation guide](https://nuxtjs.org/docs/get-started/installation).
## Configuration
You need to supply your JustCMS API token and project ID via Nuxt's runtime configuration. Open your nuxt.config.ts (or nuxt.config.js) file and add the following:
export default defineNuxtConfig({
runtimeConfig: {
public: {
justCmsToken: 'YOUR_JUSTCMS_API_TOKEN',
justCmsProject: 'YOUR_JUSTCMS_PROJECT_ID'
}
}
})
- **justCmsToken:** Your JustCMS API token required for authentication.
- **justCmsProject:** Your JustCMS project ID.
## Usage
The integration is provided as a single composable. You can import it into any component and call its functions to fetch data from JustCMS.
For full details on the composable implementation, please refer to the [composables/useJustCMS.ts](./composables/useJustCMS.ts) file.
### Example Component
Below is a simple example that fetches and displays categories:
vue
<template>
<div>
<h2>Categories</h2>
<ul>
<li v-for="cat in categories" :key="cat.slug">
{{ cat.name }}
</li>
</ul>
</div>
</template>
<script setup lang="ts">
import { useJustCMS } from '~/composables/useJustCMS'
const { getCategories } = useJustCMS()
const categories = await getCategories()
</script>
### Available Functions
The useJustCMS composable provides the following functions:
#### getCategories()
Fetches all categories for your project.
const categories = await getCategories()
// Returns: Category[]
#### getPages(options?: { category?: string; page?: number; perPage?: number })
Fetches pages with optional filtering and pagination.
// Get all pages
const allPages = await getPages()
// Get pages from a specific category
const categoryPages = await getPages({ category: 'blog' })
// Get paginated results
const paginatedPages = await getPages({ page: 1, perPage: 10 })
// Returns: { pages: Page[], total: number, currentPage: number, totalPages: number }
#### getPageBySlug(slug: string)
Fetches a specific page by its slug.
const page = await getPageBySlug('about-us')
// Returns: Page | null
#### getMenuById(id: string)
Fetches a menu and its items by ID.
const menu = await getMenuById('main-menu')
// Returns: Menu | null
#### Utility Functions
The composable also provides several helpful utility functions for working with JustCMS content:
#### isBlockHasStyle(block: ContentBlock, style: string)
Checks if a content block has a specific style (case-insensitive).
const isHighlighted = isBlockHasStyle(block, 'highlight')
// Returns: boolean
#### getLargeImageVariant(image: Image)
Gets the large variant of an image (second variant in the array).
const largeImage = getLargeImageVariant(page.coverImage)
// Returns: ImageVariant
#### getFirstImage(block: ImageBlock)
Gets the first image from an image block.
const firstImage = getFirstImage(imageBlock)
// Returns: Image
#### hasCategory(page: PageDetail, categorySlug: string)
Checks if a page belongs to a specific category.
const isBlogPost = hasCategory(page, 'blog')
// Returns: boolean