RF Hugo REST API - Website Hugo dengan Backend REST API

RF Hugo REST API - Website Hugo dengan Backend REST API

Table of Contents

Ini adalah hasil percobaan saya mengintegrasikan REST API dengan Hugo (CMS web statis).

Percobaannya dalam bentuk aplikasi todo list sederhana.

Teknologi yang Digunakan

  • HTML
  • CSS
  • JavaScript
  • REST API
  • Hugo
  • Markdown

Screenshot

Rekonstruksi

Untuk membuat aplikasi seperti ini, Anda harus membagi aplikasi ini menjadi dua:

  • Client berupa Hugo website
  • Server REST API dengan Node.js

Sekarang, kita mulai dengan server Node.js nya dulu.

Server Node.js

Buat folder baru bernama "project".

Masuk ke dalamnya kemudian buka VSCode.

Selanjutnya buat file bernama "package.json". Isinya adalah:

{
  "name": "rest-api",
  "version": "1.0.0",
  "main": "server.js",
  "scripts": {
    "dev": "nodemon server.js",
    "start": "node server.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "description": "",
  "dependencies": {
    "bcryptjs": "^3.0.2",
    "cors": "^2.8.5",
    "express": "^5.1.0"
  },
  "devDependencies": {
    "nodemon": "^3.1.10"
  }
}

Selanjutnya jalankan:

npm install

Langkah tadi menginstall seluruh dependencies yang dibutuhkan project Node.js ini.

Selanjutnya, buat file bernama "server.js". Isinya adalah:

const express = require('express');
const cors = require("cors");
const path = require('path')

const app = express();
var corsOptions = {
    origin: "http://localhost:1313",
    credentials: true,
};
app.use(cors(corsOptions));

app.use(express.json());
app.use(express.static(path.join(__dirname, 'public')));

let data = [{
    id: 0,
    name: "satu"
}, {
    id: 1,
    name: "dua"
}, {
    id: 2,
    name: "tiga"
}];

app.get("/", (req, res, nexr) => {
    res.json(data);
})

app.post("/", (req, res, nexr) => {
    data.push({
        id: data.length,
        name: req.body.name
    })

    res.json(data);
})

app.delete("/:id", (req, res, nexr) => {
    const result = data.filter((item) => item.id != req.params.id)
    data = result;
    res.json(result)
})

app.listen(3000, () => {
    console.log('Server is running on http://127.0.0.1:3000');
});

Script tadi membuatkan backend untuk aplikasi Todo sederhana yang bisa membaca daftarnya, menambahkan daftarnya, dan menghapus daftarnya.

Secara default, ada 3 todo list.

Client Hugo

Di sini saya berasumsi bahwa Anda sudah belajar dan paham tentang Hugo.

Jika belum, silakan belajar di sumber lain, karena saya tidak akan membahasnya terlalu panjang.

Sebagai permulaan, buatlah sebuah website Hugo.

Kemudian install dan gunakan theme bootstrap.

Selanjutnya, pada folder "project-hugo/static/js" buat file ini:

  • todo-inline-html.js
  • todo-shortcode-html.js
  • todo-shortcode-rest.js

Isi dari "todo-inline-html.js" adalah seperti ini:

$(document).ready(function () {
    $('#todoForm').on('submit', function (e) {
        e.preventDefault();

        const text = $('#todoInput').val().trim();
        if (text === '') return;

        const card = `
          <div class="col-12 col-md-6 col-lg-4">
            <div class="card">
              <div class="card-body d-flex justify-content-between align-items-center">
                <span>${$('<div>').text(text).html()}</span>
                <button class="btn btn-sm btn-danger btn-hapus">Hapus</button>
              </div>
            </div>
          </div>
        `;

        $('#todoList').append(card);
        $('#todoInput').val('');
    });

    // Delegasi event untuk tombol hapus
    $('#todoList').on('click', '.btn-hapus', function () {
        $(this).closest('.col-12').remove();
    });
});

Isi dari "todo-shortcode-html.js" adalah seperti ini:

$(document).ready(function () {
    $('#todoForm').on('submit', function (e) {
        e.preventDefault();

        const text = $('#todoInput').val().trim();
        if (text === '') return;

        const card = `
          <div class="col-12 col-md-6 col-lg-4">
            <div class="card">
              <div class="card-body d-flex justify-content-between align-items-center">
                <span>${$('<div>').text(text).html()}</span>
                <button class="btn btn-sm btn-danger btn-hapus">Hapus</button>
              </div>
            </div>
          </div>
        `;

        $('#todoList').append(card);
        $('#todoInput').val('');
    });

    // Delegasi event untuk tombol hapus
    $('#todoList').on('click', '.btn-hapus', function () {
        $(this).closest('.col-12').remove();
    });
});

Isi dari "todo-shortcode-rest.js" adalah seperti ini:

$(document).ready(async function () {
  axios.defaults.withCredentials = true;
  window.axiosConfig = {
    validateStatus: function (status) {
      return status >= 200;
    },
  };

  $('#todoForm').on('submit', async function (e) {
    e.preventDefault();

    const text = $('#todoInput').val().trim();
    if (text === '') return;

    const card = `
          <div class="col-12 col-md-6 col-lg-4">
            <div class="card">
              <div class="card-body d-flex justify-content-between align-items-center">
                <span>${$('<div>').text(text).html()}</span>
                <button class="btn btn-sm btn-danger btn-hapus">Hapus</button>
              </div>
            </div>
          </div>
        `;

    $('#todoList').append(card);
    $('#todoInput').val('');

    // kirim ke server
    const ret = await axios.post(
      "http://127.0.0.1:3000/",
      {
        name: text
      },
      axiosConfig
    );

    console.log(ret)
  });

  // Delegasi event untuk tombol hapus
  $('#todoList').on('click', '.btn-hapus', async function () {
    // $(this).closest('.col-12').remove();
    const deleteID = $(this).closest('.col-12').attr("id")
    console.log(deleteID)

    $('#todoList').empty();

    const ret = await axios.delete(
      `http://127.0.0.1:3000/${deleteID}`,
      {
      },
      axiosConfig
    );

    console.log(ret)

    ret.data.forEach((item, index) => {
      const card1 = `
      <div id="${item.id}" class="col-12 col-md-6 col-lg-4">
        <div class="card">
          <div class="card-body d-flex justify-content-between align-items-center">
            <span>${$('<div>').text(item.name).html()}</span>
            <button class="btn btn-sm btn-danger btn-hapus">Hapus</button>
          </div>
        </div>
      </div>
    `;
      $('#todoList').append(card1);
    })
  });

  // init
  const ret = await axios.get(
    "http://127.0.0.1:3000/",
    {
    },
    axiosConfig
  );

  console.log(ret)

  ret.data.forEach((item, index) => {
    const card1 = `
      <div id="${item.id}" class="col-12 col-md-6 col-lg-4">
        <div class="card">
          <div class="card-body d-flex justify-content-between align-items-center">
            <span>${$('<div>').text(item.name).html()}</span>
            <button class="btn btn-sm btn-danger btn-hapus">Hapus</button>
          </div>
        </div>
      </div>
    `;
    $('#todoList').append(card1);
  })

});

Kemudian, download axios dan jquery, lalu masukkan ke:

  • project-hugo/static/vendor/axios/axios.min.js
  • project-hugo/static/vendor/jquery/jquery.min.js

Kemudian, di folder "project-hugo/layouts/shortcodes", buat script html ini:

  • todo-shortcode-html.html
  • todo-shortcode-rest.html

isi dari "todo-shortcode-html.html" adalah seperti ini:

<div class="container py-5">
    <form id="todoForm" class="mb-4">
        <div class="input-group">
            <input type="text" class="form-control" id="todoInput" placeholder="Tambahkan todo..." required />
            <button type="submit" class="btn btn-primary">Tambah</button>
        </div>
    </form>
    <div id="todoList" class="row g-3">
    </div>
</div>
<script src="/vendor/jquery/jquery.min.js"></script>
<script src="/js/todo-shortcode-html.js"></script>

Isi dari "todo-shortcode-rest.html" adalah seperti ini:

<div class="container py-5">
    <form id="todoForm" class="mb-4">
        <div class="input-group">
            <input type="text" class="form-control" id="todoInput" placeholder="Tambahkan todo..." required />
            <button type="submit" class="btn btn-primary">Tambah</button>
        </div>
    </form>
    <div id="todoList" class="row g-3">
    </div>
</div>
<script src="/vendor/axios/axios.min.js"></script>
<script src="/vendor/jquery/jquery.min.js"></script>
<script src="/js/todo-shortcode-rest.js"></script>

Pada folder "project-hugo/content", buat script markdown ini:

  • todo-inline-html.md
  • todo-shortcode-html.md
  • todo-shortcode-rest.md

Isi dari "todo-inline-html.md" adalah sebagai berikut:

---
title: "Todo Inline HTML"
description: ""
date: 2025-05-30T04:43:14+07:00
draft: false
hidden: false
categories: ["General"]
tags: []
keywords: ["todo"]
author: ""
---

## Ini adalah Todo Inline HTML

Bisa, tapi tidak boleh ada baris kosong.

<!--more-->

<div class="container py-5">
    <form id="todoForm" class="mb-4">
        <div class="input-group">
        <input type="text" class="form-control" id="todoInput" placeholder="Tambahkan todo..." required />
        <button type="submit" class="btn btn-primary">Tambah</button>
        </div>
    </form>
    <div id="todoList" class="row g-3">
    </div>
</div>
<script src="/vendor/jquery/jquery.min.js"></script>
<script src="/js/todo-inline-html.js"></script>

Isi dari "todo-shortcode-html.md" adalah sebagai berikut:

---
title: "Todo Shortcode HTML"
description: ""
date: 2025-05-30T04:43:14+07:00
draft: false
hidden: false
categories: ["General"]
tags: []
keywords: ["todo"]
author: ""
---

## Ini adalah Todo Shortcode HTML

Cara yang dianjurkan.

<!--more-->

{{< todo-shortcode-html >}}

Isi dari "todo-shortcode-rest.md" adalah sebagai berikut:

---
title: "Todo Shortcode REST API"
description: ""
date: 2025-05-30T04:43:14+07:00
draft: false
hidden: false
categories: ["General"]
tags: []
keywords: ["todo"]
author: ""
---

## Ini adalah Todo Shortcode yang Disimpan di Backend

Dengan menggunakan shortcode.

<!--more-->

{{< todo-shortcode-rest >}}

Download Source Code-nya