Skip to content

Structured Content with Nested Collections — Using the API: A Simple Vanilla TypeScript Example

00:00 / 00:00

03. Using the API: A simple Vanilla TypeScript example

Introduction

We now have courses in Content Island linked to their list of lessons. How do we use this from code?

In this video, we’ll create a minimal project using Vanilla TypeScript to understand how to interact with the Content Island API without adding unnecessary complexity.

Creating the Project

We’ll create a blank Vanilla TypeScript project without subfolders. Run the command:

npm create vite@latest .

Clean up the project: remove the counter and clear the main.ts file.

Install project dependencies:

npm install

Now install the Content Island client:

npm install @content-island/api-client

Defining the Data Model

Create a file under src called model.ts.

This code is taken from the Content Island project.

./src/model.ts

import type { Media } from "@content-island/api-client";

export interface Training {
  id: string;
  language: "en";
  title: string;
  slug: string;
  thumbnail: Media;
  overview: string;
  lessons?: string[]; // Stores the ID of the related entity
}

export interface Lesson {
  id: string;
  language: "en";
  title: string;
  slug: string;
  content: string;
  video: string;
}

Notice the lessons field:

  • First, it’s marked as optional (see the question mark?), because we didn’t mark it as required in the Content Island data model.

  • Secondly, it’s an array of strings. This is because Content Island returns a list of IDs for the lessons, not the full objects. You can make a separate request to fetch the lesson details when needed.

Initializing Content Island and Course API

Create a file called api.ts and initialize the Content Island client.

./src/api.ts

import { createClient } from "@content-island/api-client";

// For simplicity, the token is hardcoded. In a real project, you should use
// environment variables or a secret management system.
// And call this code from the server
const client = createClient({
  accessToken: "a2bb1def2090a842ab3e331e33693e2c", // Replace with your real token
});

Let’s start by fetching the data of a specific course. Create a function called getTraining and pass it the course id.

Add this to the end of api.ts

import { ContentIsland } from '@content-island/api-client';
+ import type { Training } from './model';

// For simplicity, the token is hardcoded. In a real project, use environment variables and call this from the server.
const contentIsland = new ContentIsland({
 accessToken: "a2bb1def2090a842ab3e331e33693e2c",
});

+ export async function getTraining(id: string): Promise<Training> {
+  const training = await client.getContent<Training>({id});
+  return training;
+ }

Now let’s move on to main.ts

./src/main.ts

import "./style.css";
import { getTraining } from "./api";

async function main() {
  const training = await getTraining("6882199268fb58095585e4be");

  const appContainer = document.getElementById("app");

  if (appContainer) {
    appContainer.innerHTML = `<h1>${training.title}</h1>`;
  } else {
    console.error("App container not found");
  }
}

main();

Now let’s display the list of lessons for the course. Create a function called getLessons and pass it the list of IDs of the lessons to retrieve:

Add this to the end of api.ts

./src/api.ts

export async function getLessons(ids: string[]): Promise<Lesson[]> {
  const lessons = await client.getContentList<Lesson>({
    contentType: "lesson",
    id: { in: ids },
  });
  return lessons;
}

Update main.ts to display the list of course lessons:

./src/main.ts

- import { getTraining } from "./api";
+ import { getTraining, getLessons } from "./api";

+ const showLessons = (lessons: Lesson[]) => {
+  const appContainer = document.getElementById("app");
+  if (appContainer) {
+    const lessonsList = lessons.map(lesson => `<li>${lesson.title}</li>`).join('');
+    appContainer.innerHTML += `<h2>Lessons:</h2><ul>${lessonsList}</ul>`;
+  } else {
+    console.error("App container not found");
+  }
+ }

async function main() {
  const training = await getTraining("b3d8c1f2-4e5a-4c6b-9f0e-7a8b9c0d1e2f");
+ const lessons = training.lessons ? await getLessons(training.lessons) : [];

  const appContainer = document.getElementById("app");

  if (appContainer) {
    appContainer.innerHTML = `<h1>${training.title}</h1>`;
+     showLessons(lessons);
  } else {
    console.error("App container not found");
  }
}

Now we have both the course data and its lesson details.

In this project, we’ve covered the basics to understand the concept. In the next video, we’ll look at a more complete implementation.