N

Nokfa Docs

Current: framework-next.js

ไม่มีชื่อบทความ

ถ้าเราใช้ Next.js แล้วแยกเนื้อหาเป็นไฟล์ JSON (เช่นสำหรับรองรับหลายภาษา หรือเพื่อความเป็นระบบ), แล้วในประโยค ๆ หนึ่งมีบางคำที่ต้องใส่ลูกเล่น (เช่น เน้นสี, เอียง, หรือทำให้เป็นลิงก์), วิธีที่นิยมทำกันคือ ใช้การทำ mark หรือ tag ในเนื้อหา JSON แล้วแปลงกลับเป็น JSX ตอน render

วิธีทำ: ใส่ markup ลงใน JSON แล้ว parse ที่ component

1. ตัวอย่าง JSON

{
  "greeting": "สวัสดี <strong>คุณผู้ใช้</strong> ยินดีต้อนรับ"
}

หรือถ้าอยากซับซ้อนขึ้น:

{
  "greeting": [
    "สวัสดี ",
    { "type": "strong", "text": "คุณผู้ใช้" },
    " ยินดีต้อนรับ"
  ]
}

2. Render แบบแปลง HTML string เป็น JSX

ถ้าใช้แบบแรก (<strong>...</strong>) เราสามารถใช้ dangerouslySetInnerHTML ได้:

export default function Greeting({ content }) {
  return (
    <div dangerouslySetInnerHTML={{ __html: content.greeting }} />
  )
}

ข้อควรระวัง: ต้องมั่นใจว่า content ปลอดภัย (sanitize แล้ว) เพื่อป้องกัน XSS


3. Render แบบ object (ปลอดภัยกว่า)

ถ้าใช้แบบ array + object (แบบที่สอง), เขียนตัว parser ได้แบบนี้:

function renderRichText(richTextArray) {
  return richTextArray.map((item, index) => {
    if (typeof item === 'string') return item;
    if (item.type === 'strong') return <strong key={index}>{item.text}</strong>;
    if (item.type === 'em') return <em key={index}>{item.text}</em>;
    if (item.type === 'link') return <a key={index} href={item.href}>{item.text}</a>;
    return item.text;
  });
}

แล้วใช้แบบนี้:

export default function Greeting({ content }) {
  return (
    <div>
      {renderRichText(content.greeting)}
    </div>
  )
}

4. ถ้าใช้ i18n library อย่าง i18next

จะมีฟีเจอร์ที่ชื่อว่า Trans component ที่ช่วยให้เราทำสิ่งนี้ได้อย่างสะดวกโดยใช้ <0>, <1> แบบนี้ในข้อความ เช่น:

{
  "greeting": "สวัสดี <strong>{{name}}</strong> ยินดีต้อนรับ"
}

ถ้าบอกลักษณะของ "ลูกเล่น" ที่อยากทำเพิ่มเติม (เช่น ใส่ hover, ทำ tooltip, ทำ animation ฯลฯ) เราสามารถวางโครง JSON และ renderer ให้ได้ละเอียดขึ้นอีกนะ.