Home > OS >  Vue Vite CosmicJS
Vue Vite CosmicJS

Time:01-30

I'm building a blog SPA website as a hobby, and trying to figure out what would be the best way to get the smallest latency to acquire posts from a database.

So far I've tried Wordpress, but its API at least at the very first initial request every time, with API cache enabled, takes about a second (800-1100ms) to load only a handful posts - 6 to be precise each with a picture and about 2-300 words, and this is only for testing.

So I'm looking around for other possible solutions to make the request faster but stay free of charge and came across Cosmic JS.

I installed the cosmicjs module, but getting all sorts of errors as I try to initiate the requests, based on their documentation which looks like the following:

<script>
const Cosmic = require('cosmicjs')
const api = Cosmic()
// Set these values, found in Bucket > Settings after logging in at https://app.cosmicjs.com/login
const bucket = api.bucket({
  slug: "YOUR_BUCKET_SLUG",
  read_key: "YOUR_BUCKET_READ_KEY"
})
</script>

First, you can't use require in Vite, so I've changed this

const Cosmic = require('cosmicjs')

to this

import Cosmic from "cosmicjs"

But I'm still getting error:

ReferenceError: process is not defined
    at node_modules/cosmicjs/dist/helpers/constants.js (cosmicjs.js?v=2a84de6d:1367:19)
    at __require2 (chunk-NKHIPFFU.js?v=2a84de6d:15:50)
    at node_modules/cosmicjs/dist/main.js (cosmicjs.js?v=2a84de6d:1387:21)
    at __require2 (chunk-NKHIPFFU.js?v=2a84de6d:15:50)
    at node_modules/cosmicjs/dist/index.js (cosmicjs.js?v=2a84de6d:3359:23)
    at __require2 (chunk-NKHIPFFU.js?v=2a84de6d:15:50)
    at cosmicjs.js?v=2a84de6d:3371:16ű

Can't figure out what to do next to even make this work, currently my code looks like this for the cosmic request part:

import Cosmic from "cosmicjs"

const api = Cosmic();


const bucket = api.bucket({
  slug: "NOT-GOING-TO-SHOW-SORRY-AND-THX",
  read_key: "NOT-GOING-TO-SHOW-SORRY-AND-THX",
});

const data = await bucket.objects
  .find({
    type: "posts", // Object Type slug
  })
  .props("title,slug,metadata") // response properties
  .limit(10); // number of Objects to be returned 

  console.log(data)

Any idea might be a good help, thanks in advance

CodePudding user response:

Figured it out:

So anyone trying to use in Vite ANY node module that has process as a function in any part in that module, should do the following

In your vite.config.ts or vite.config.js add the following

export default defineConfig({
  // ...
  define: {
    'process.env': process.env
  }
})

And instead of require

const Cosmic = require('cosmicjs')

always use import

import Cosmic from "cosmicjs"

Besides that, everything works the same as in other API requests, so eg. in my case, I'm API requesting posts from my cosmic js Bucket

<script setup lang="ts">

import { ref } from "vue";
import { onMounted } from "vue";
import moment from "moment";
import Cosmic from "cosmicjs"

const api = Cosmic();
const posts = ref([] as any);

const isLoading = ref(false);


const bucket = api.bucket({
  slug: "c27229f0-9018-11ed-b853-65fa50acc7e7",
  read_key: "G71yMNlvizQCtrvVyp9Z1AecQp8a4RTr5dl9uEGi6nst9FNQIW",
});
async function fetchData() {
      isLoading.value = true
      const data = await bucket.objects.find({
        type: 'posts'
      }).props('slug,title,content,metadata') // Limit the API response data by props
      posts.value = data.objects
      isLoading.value = false

      console.log(posts)
    }


onMounted(async () => {
fetchData();    
});

</script>

and the iterate through them in my template

<template>

    <ul v-if="!isLoading"  v-for="post in posts" :key="post.slug">
      <div >
        <a
          ><router-link
            :to="/blog/   post.slug"
            key="post.id"
            
          >
          </router-link
        ></a>
        <img
          v-if="post.metadata.image != null"
          
          :src="post.metadata.image.imgix_url"
          :alt="post.title"
        />
        <img v-else src="@/assets/logos/favicon-big.png" />
        <div >
          <p>
            {{ moment(post.date).fromNow()   " "   "ago" }}
          </p>
        </div>

        <div >
          <h1 >{{ post.title }}</h1>

          <p v-html="post.excerpt" ></p>
        </div>
      </div>
    </ul>
</template>

As a last sidenote, this works flawlessly compared to Wordpress API requests, I was using Wordpress for my backend CMS and even with API cache plugin enabled, it took around 800-1100ms to load the posts, now that time shrank to about 30ms for the API request of the text based data, and extra 30-40ms for each image (thumbnails for the posts).

  • Related