Thai Address (Bilingual)

แก้ปัญหาการหาข้อมูลที่อยู่ไทยที่เป็น 2 ภาษาแล้วต้องมานั่งคลีนเอง ด้วยฐานข้อมูลที่เบาที่สุด ออกแบบมาเพื่อ Developer โดยเฉพาะ

Thai Address (Bilingual) Project
About Project

ฐานข้อมูลที่อยู่ไทยสำหรับ Developer

Thai Address (Bilingual) คือ Open Source Library ที่สร้างขึ้นมาเพื่อแก้ Pain Point ของนักพัฒนา ที่มักจะเจอปัญหาข้อมูลที่อยู่ไทยไม่ครบถ้วน, ไม่มีภาษาอังกฤษ, หรือขนาดไฟล์ใหญ่เกินไป เราจึงนำข้อมูลมาจัดระเบียบใหม่ ให้คลีน เบา และพร้อมใช้งานทันทีในทุกโปรเจกต์ ไม่ว่าจะเป็นการทำระบบเลือกจังหวัด-อำเภอ-ตำบล หรือระบบคำนวณค่าขนส่งก็ตาม

ตัวอย่างการใช้งานจริง

ลองเลือกข้อมูลจังหวัด อำเภอ และตำบลด้านล่าง เพื่อดูรูปแบบและโครงสร้าง JSON ที่ได้จากฐานข้อมูลแบบเรียลไทม์

Interactive Live Demo

ลองเลือกที่อยู่เพื่อดูโครงสร้างข้อมูลจริงจาก GitHub

กำลังโหลดฐานข้อมูลจาก GitHub...

ทำไมควรเลือกใช้ฐานข้อมูลนี้?

Bilingual Ready

รองรับทั้งไทยและอังกฤษแบบสมบูรณ์ คลีน ไม่มีคำนำหน้า Khet/Amphoe ให้กวนใจตอนทำ UI

DOPA Standard

ใช้รหัสมาตรฐานกรมการปกครอง (DOPA Codes) อ้างอิงได้แม่นยำทุกระดับจังหวัดถึงตำบล

Ultra Lightweight

โครงสร้าง JSON แบบ Key ย่อ (p, n, s) ช่วยลดขนาดไฟล์ลงกว่า 60% เหลือเพียง ~655 KB

Always Fresh

มีสคริปต์ Sync ให้ในตัว ดึงข้อมูลล่าสุดจาก GitHub เข้าโปรเจกต์คุณได้ง่ายๆ ไม่ต้องโหลดเอง

database.json
[
  {
    "i": "10",
    "p": { "th": "กรุงเทพมหานคร", "en": "Bangkok" },
    "d": [
      {
        "i": "1001",
        "n": { "th": "พระนคร", "en": "Phra Nakhon" },
        "s": [
          {
            "i": "100101",
            "n": { "th": "พระบรมมหาราชวัง", "en": "Phra Borom Maha Ratchawang" },
            "z": "10200"
          }
        ]
      }
    ]
  }
]

3 ขั้นตอน สู่การใช้งานจริง

1

สร้าง Sync Script

ไม่ต้องดาวน์โหลดไฟล์มาวางเองให้เหนื่อย แค่สร้างไฟล์ scripts/sync-address.js แล้ววางโค้ดนี้ลงไป:

scripts/sync-address.js
const fs = require('fs');
const https = require('https');
const path = require('path');

// เปลี่ยนเป็น .min.json หากต้องการความเบาที่สุด
const RAW_URL = 'https://raw.githubusercontent.com/hudchew/thai-address/main/thailand-address-bilingual.min.json';

const LOCAL_PATH = './src/lib/data/thailand-address.json';
const dir = path.dirname(LOCAL_PATH);

if (!fs.existsSync(dir)){
    fs.mkdirSync(dir, { recursive: true });
}

console.log('⏳ กำลังดาวน์โหลดข้อมูลจาก hudchew/thai-address...');

https.get(RAW_URL, (res) => {
    if (res.statusCode !== 200) {
        console.error('❌ ไม่สามารถดึงข้อมูลได้ (Status Code: ' + res.statusCode + ')');
        return;
    }
    const file = fs.createWriteStream(LOCAL_PATH);
    res.pipe(file);
    file.on('finish', () => {
        file.close();
        console.log('✅ อัปเดตข้อมูลที่อยู่ล่าสุดเรียบร้อยแล้ว!');
        console.log('📍 ไฟล์ถูกบันทึกไว้ที่: ' + LOCAL_PATH);
    });
}).on('error', (err) => {
    console.error('❌ เกิดข้อผิดพลาด:', err.message);
});
2

ลงทะเบียนใน package.json

เพิ่มคำสั่งในส่วน scripts เพื่อให้เรียกใช้งานได้ง่ายๆ:

"sync-address": "node scripts/sync-address.js"
3

รันและเริ่มใช้งาน!

คราวนี้แค่รัน npm run sync-address ข้อมูลที่อยู่ล่าสุดก็จะมานอนรอในโปรเจกต์คุณทันที

ไฟล์จะถูกเก็บที่: ./src/lib/data/thailand-address.json

ใช้งานในโปรเจกต์ของคุณ

เลือก Framework ที่คุณใช้ แล้วก๊อบปี้โค้ดไปวางได้เลย เราเตรียมทุกอย่างไว้ให้พร้อมแล้ว

ตัวอย่าง Cascading Select (จังหวัด → อำเภอ → ตำบล)

ใช้ React State พื้นฐานร่วมกับข้อมูลที่ดึงมา

components/AddressSelector.tsx
import { useState } from 'react';
import data from '@/lib/data/thailand-address.json';
import { ThaiProvince, ThaiDistrict } from '@/types/thai-address';

export default function AddressSelector() {
  const [selectedProvince, setSelectedProvince] = useState<ThaiProvince | null>(null);
  const [selectedDistrict, setSelectedDistrict] = useState<ThaiDistrict | null>(null);
  const lang = 'th';

  return (
    <div className="space-y-4">
      <select onChange={(e) => {
        const p = data.find(i => i.i === e.target.value);
        setSelectedProvince(p ?? null);
        setSelectedDistrict(null);
      }}>
        <option value="">เลือกจังหวัด</option>
        {data.map(item => (
          <option key={item.i} value={item.i}>{item.p[lang]}</option>
        ))}
      </select>

      <select
        disabled={!selectedProvince}
        onChange={(e) => {
          const d = selectedProvince?.d.find(i => i.i === e.target.value);
          setSelectedDistrict(d ?? null);
        }}
      >
        <option value="">เลือกอำเภอ</option>
        {selectedProvince?.d.map(item => (
          <option key={item.i} value={item.i}>{item.n[lang]}</option>
        ))}
      </select>
    </div>
  );
}

🤝 อยากช่วยทำให้ข้อมูลดีขึ้นไหม?

พบคำสะกดผิด? หรืออยากเพิ่มตำบลใหม่ที่เพิ่งตั้งขึ้น? เรายินดีต้อนรับทุกคน! ฐานข้อมูลนี้จะดีที่สุดได้เพราะพวกเราช่วยกัน

อ่านคู่มือการมีส่วนร่วม