Tự tạo tool online bằng HTML, CSS, JavaScript — Hướng dẫn A→Z

Cập nhật: 2025

Muốn có một website Tools nhỏ gọn (random number, QR, counter, image compressor...) — bạn hoàn toàn có thể tự làm bằng HTML/CSS/vanilla JS. Bài này hướng dẫn chi tiết: từ cấu trúc file, code mẫu cho từng tool, đến cách tối ưu SEO và deploy lên Vercel/Netlify.

Mục lục

1. Tại sao nên làm tool bằng HTML/CSS/JS?

Lợi ích:

2. Cấu trúc dự án (file/folder)

Gợi ý cấu trúc tối giản:


/mytools
  /assets
    /css
      style.css
      blog.css
    /js
      main.js
      mobile-menu.js
      theme.js
    /img
  /partials
    header.html
    footer.html
  /tools
    /random-number
      index.html
      script.js
    /qr-generator
      index.html
      script.js
    /character-counter
      index.html
      script.js
    /image-compress
      index.html
      script.js
  /blog
    bai-1-hoc-js-co-ban.html
    bai-2-hoc-csharp-cho-nguoi-moi.html
    bai-3-tu-tao-tool-bang-js.html
  index.html
  sitemap.xml
  robots.txt

Mỗi tool có folder riêng: URL đẹp (ví dụ /tools/qr-generator/). Các assets chung (CSS/JS/header/footer) đặt ở /assets/partials.

3. Ví dụ cụ thể — code mẫu cho 4 tool

3.1 Random Number (JS thuần)

Mô tả: nhập min/max → bấm Random → hiển thị & copy.


// script.js (tools/random-number/script.js)
const minInput = document.getElementById("min");
const maxInput = document.getElementById("max");
const btn = document.getElementById("randomBtn");
const resultBox = document.getElementById("result");
const copyBtn = document.getElementById("copyBtn");

btn.addEventListener("click", () => {
  const min = parseInt(minInput.value);
  const max = parseInt(maxInput.value);
  if (isNaN(min) || isNaN(max) || min > max) {
    resultBox.textContent = "Giá trị không hợp lệ!";
    return;
  }
  const random = Math.floor(Math.random() * (max - min + 1)) + min;
  resultBox.textContent = random;
});

HTML tương ứng (tối giản):


<input id="min" type="number" value="1">
<input id="max" type="number" value="100">
<button id="randomBtn">Random</button>
<div id="result">?</div>

3.2 QR Generator (dùng thư viện client-side)

Sử dụng `qrcode` trên CDN để tạo DataURL và hiển thị ảnh.


// script.js (tools/qr-generator/script.js)
const generateBtn = document.getElementById("generateBtn");
const textInput = document.getElementById("qrInput");
const qrResult = document.getElementById("qrResult");
generateBtn.addEventListener("click", () => {
  const text = textInput.value.trim();
  if(!text) return qrResult.innerHTML = "<p>Nhập nội dung!</p>";
  QRCode.toDataURL(text, { width: 300 }, (err, url) => {
    if(err) return;
    qrResult.innerHTML = '<img src="' + url + '" alt="QR">';
  });
});

3.3 Character Counter (đếm ký tự, từ, dòng)


// script.js (tools/character-counter/script.js)
const textInput = document.getElementById("textInput");
const charCount = document.getElementById("charCount");
const wordCount = document.getElementById("wordCount");
const lineCount = document.getElementById("lineCount");

function updateCount() {
  const text = textInput.value;
  charCount.textContent = text.length;
  const words = text.trim().split(/\s+/).filter(Boolean);
  wordCount.textContent = words.length;
  lineCount.textContent = text.split(/\n/).length;
}
textInput.addEventListener("input", updateCount);
updateCount();

3.4 Image Compressor (client-side bằng canvas)

Nén ảnh nhanh bằng canvas → toDataURL('image/jpeg', quality).


// script.js (tools/image-compress/script.js)
function compressImage(file, quality, cb) {
  const reader = new FileReader();
  reader.readAsDataURL(file);
  reader.onload = e => {
    const img = new Image();
    img.src = e.target.result;
    img.onload = () => {
      const canvas = document.createElement('canvas');
      canvas.width = img.width; canvas.height = img.height;
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img,0,0);
      const dataUrl = canvas.toDataURL('image/jpeg', quality);
      cb(dataUrl);
    };
  };
}

Ghi chú: client-side compression phù hợp cho ảnh nhỏ → nếu batch hoặc ảnh lớn (nghìn ảnh), cân nhắc server-side.

4. Giao diện & UX — những thứ cần có

Một tool chuyên nghiệp nên có:

Ví dụ HTML skeleton (tool page):


<section class="container tool-container">
  <h1>Tạo QR Code</h1>
  <p class="subtitle">Tạo QR từ URL hoặc text, tải PNG.</p>
  <textarea id="qrInput"></textarea>
  <button id="generateBtn">Tạo QR</button>
  <div id="qrResult"></div>
</section>

5. Tối ưu SEO cho tool (cần làm ngay)

Mẫu JSON-LD (SoftwareApplication):


<script type="application/ld+json">
{
  "@context":"https://schema.org",
  "@type":"SoftwareApplication",
  "name":"Tạo QR Code - BapTools",
  "url":"https://yourdomain.com/tools/qr-generator/",
  "description":"Tạo mã QR miễn phí từ URL hoặc văn bản, tải PNG.",
  "applicationCategory":"Utilities"
}
</script>

6. Deploy nhanh (Vercel / Netlify)

Vercel / Netlify hỗ trợ static site trực tiếp từ GitHub:

  1. Push repo lên GitHub
  2. Đăng nhập Vercel / Netlify → link repo → deploy
  3. Set domain, bật HTTPS
  4. Submit sitemap lên Google Search Console

Tips: dùng _headers / _redirects (Netlify) hoặc config (Vercel) để redirect sạch và cache static tốt.

7. Kiếm tiền & đo lường

Gợi ý monetization:

Tracking & phân tích:

8. Kết luận & bước tiếp theo

Làm tool online rất hợp lý: chi phí thấp, triển khai nhanh, dễ SEO. Bắt đầu bằng vài tool cần thiết → tạo nội dung SEO xung quanh từng tool → đẩy traffic bằng social + share → bật ads/affiliate khi có lượng truy cập.

Bước làm ngay (Checklist)

  1. Tạo repo & cấu trúc folder
  2. Làm 3–5 tool đầu tiên (random, qr, counter, image compress, json formatter)
  3. Viết 1 bài blog cho mỗi tool (200–600 từ)
  4. Deploy lên Vercel/Netlify
  5. Submit sitemap, share lên social & reddit