Trying to get NocoDB to work in Astro Framework

Hey guys, for the last couple days I´ve been trying to add NocoDB to Astro but no success. I tried figuring it out using ChatGPT but it doesn’t work out and no information anywhere. Seems like no one published information on that particular topics thus far. I used to use Airtable with Gridsome but this is entirely different.
Can someone help?

Thanks in advance!

Would be helpful to understand what is the astro, how are you trying to ‘add’ and what is the usecase for using them together?

All I need is a basic example on how to use and display data from NocoDB in Astro. I want to use it for blog type content management.

If you are looking for APIs - here is how you can find APIs for your nocodb base.

Not what I’ve been asking for.

I will leave a link on how to add nocodb to an express app.

However, its not clear from the above what is the issue. Perhaps the link will help and you could reach out astro team.

The issue is I’m looking for a code example on how to use Noco in Astro but I can’t find anything. This could be helping people facing the same issue in the future as well. Gridsome had intigrations for all data sources and starter templates to make it easy for beginners. I might publish a Astro NocoDB starter once I figure it out.

1 Like

Sorry that this is a bit of a stale topic, but as someone who’s done a little work integrating Astro.js and NocoDB, I thought I might try and provide some context.

Astro is a Node-based static website generator with a lot of powerful capabilities. It’s very good at ingesting APIs from different data sources and using them to build content websites. It already has an Airtable adapter but a NocoDB one would be very valuable.

Nonetheless, you can integrate the two systems manually by taking the API feed from a NocoDB table and adding it to page and index templates. See for example the documentation on Data Fetching

2 Likes

Following up on my last post, I thought I’d post some code samples that might help other uses make sense of using Astro and NocoDB.

Firstly get the latest version and enable the experimental Content Layer feature in the astro config file. This won’t be needed when version 5 drops.

Context: I’m building a little tracker site for my art supplies, so the code will reflect that.

// src/content/config.ts

import { defineCollection, reference, z } from 'astro:content';
 
const supplies = defineCollection({
    loader: async () => {
      const response = await fetch('NOCODB URL', {
        headers: {
                   Accept: "application/json",
                   "xc-token": "AUTHENTICATION TOKEN",
                   },
      });
      const data = await response.json();
      // Must return an array of entries with an id property, or an object with IDs as keys and entries as values
      return data.list.map((supply: any) => ({
        id: supply.Id.toString(), //id has to be a string not a number
        name: supply.Name,
        mediumName: supply.Medium.Name,
        rangeTitle: supply.Range?.Title,
        hue: supply.ColourGrouping,
        ...supply,
      }));
    },
    // optionally define a schema using Zod
    schema: z.object({
      id: z.string(),
      name: z.string(),
      mediumName: z.string(),
      hue: z.string(),
      rangeTitle: z.string().optional(),
      // ...
    }),
  });
 
export const collections = {
	supplies,
};

Okay now the front matter of an index view:

import { getCollection, getEntry } from 'astro:content';

const allSupplies = await getCollection('supplies');

Ultra dirty nasty unordered list of items in the collection:

<ul>
{allSupplies.map((item: any) => (
  <li><a href={item.data.id}>{item.data.Id} {item.data.name} {item.data.mediumName} {item.data.hue}</a></li>
))}
</ul>

Here’s the [id].astro file that generates individual pages out of each record:

---
import type { GetStaticPaths } from "astro";
import { getCollection, type CollectionEntry } from "astro:content";
import Layout from "../../layouts/Layout.astro";


export const getStaticPaths: GetStaticPaths = async () => {
  const supplies = await getCollection("supplies");
  return supplies.map((supply) => ({
    params: {
      id: supply.id,
    },
    props: { supply },
  }));
};


type Props = { supply: CollectionEntry<"supplies"> };
const { supply } = Astro.props;

---

<Layout title={supply.data.name}>
    <h1>{supply.data.name}</h1>
</Layout>

Pretty bare bones but it works, should be enough to build on? Hope this helps people out anyway. I might stick this post on the astro subreddit too.

3 Likes