Create Integration Guide for Any Framework in Few Minutes

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 AI and a prompt to generate any integration

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.

1. Choose the right AI model

For creating framework integrations, it's crucial to use AI models that excel at reasoning and following complex instructions. We recommend using powerful language models like OpenAI o3-mini or Deepseek R1 for this task. These models are specifically designed to:
  • Understand complex technical requirements
  • Generate detailed, step-by-step instructions
  • Provide complete and accurate integration code
  • Follow structured patterns consistently
Reasoning models are particularly effective because they can understand the context of your framework and generate appropriate integration patterns. They process your requirements more thoroughly and produce more reliable results compared to simpler language models.

2. Use a prompt we prepared to generate the integration

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