<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Blog - Thành Nam Nguyễn]]></title><description><![CDATA[<p>Trang blog cá nhân của Thành Nam Nguyễn, chia sẻ các thông tin, kiến thức, mẹo về công nghệ, lập trình, v.v</p>
]]></description><link>https://blog.thanhnamnguyen.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1756618255566/be4f1856-599c-49d7-98e2-2b87d313451f.png</url><title>Blog - Thành Nam Nguyễn</title><link>https://blog.thanhnamnguyen.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Fri, 10 Apr 2026 16:01:31 GMT</lastBuildDate><atom:link href="https://blog.thanhnamnguyen.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><atom:link rel="first" href="https://blog.thanhnamnguyen.dev/rss.xml"/><atom:link rel="next" href="https://blog.thanhnamnguyen.dev/rss.xml?after=NjZmZjVhNGI3Y2IzYjQ5Njg4ZGU2YTRhXzIwMjQtMTAtMDRUMDM6MDA6MjcuOTc4Wg=="/><item><title><![CDATA[Các extension chặn quảng cáo YouTube & Website hiệu quả]]></title><description><![CDATA[<p>Nu bn tng <strong>bc mnh v ang xem YouTube th b qung co chen ngang</strong>, hoc ang c bi trn website th pop-up bt ln che kn mn hnh, th yn tm  chuyn ny khng ch mnh bn gp u. Qung co online ngy cng nhiu, xut hin  khp ni, t video YouTube cho n cc trang tin tc, blog hay din n.</p>
<p>Chnh v vy, <strong>extension chn qung co YouTube v website</strong>  tr thnh tr th c lc ca rt nhiu ngi dng ph thng. Khng cn rnh cng ngh, khng phi ci t phc tp, ch vi c click l bn  c th <strong>xem video mt hn, lt web gn gng hn</strong>.</p>
<p><strong>Bi vit ny s gip bn:</strong></p>
<ul>
<li><p>Hiu extension chn qung co l g</p>
</li>
<li><p>Bit cc extension chn qung co YouTube &amp; website ph bin nht</p>
</li>
<li><p>Nm r u  nhc im tng cng c</p>
</li>
<li><p>Hiu cch YouTube ang chng adblock</p>
</li>
<li><p>Bit cch dng sao cho hp l v bn lu</p>
</li>
</ul>
<h2 id="heading-extension-chan-quang-cao-la-gi">Extension chn qung co l g?</h2>
<p>Ni n gin cho d hiu, <strong>extension chn qung co</strong> l tin ch m rng ci thm vo trnh duyt nh Chrome, Edge, Firefox Sau khi ci, extension s t ng:</p>
<ul>
<li><p>Chn qung co trc, gia v sau video YouTube</p>
</li>
<li><p>n banner qung co trn website</p>
</li>
<li><p>Ngn pop-up, qung co che ni dung</p>
</li>
<li><p>Chn video qung co t ng pht</p>
</li>
<li><p>Gim cc m theo di (tracking)</p>
</li>
</ul>
<p>Vi ngi dng ph thng, bn gn nh <strong>khng cn chnh g thm</strong>. Ci xong l dng c ngay.</p>
<h2 id="heading-vi-sao-nen-dung-extension-chan-quang-cao">V sao nn dng extension chn qung co?</h2>
<p>Khng phi ngu nhin m ngy cng nhiu ngi tm n extension chn qung co. Mt vi l do rt thc t gm:</p>
<ul>
<li><p>Qung co YouTube xut hin qu thng xuyn</p>
</li>
<li><p>Nhiu qung co khng th b qua</p>
</li>
<li><p>Website c qu nhiu banner gy ri mt</p>
</li>
<li><p>Pop-up bt ln bt ng, d bm nhm</p>
</li>
<li><p>Qung co lm trang web ti chm</p>
</li>
</ul>
<p>Ni vui mt cht th, dng extension chn qung co ging nh <strong>dn sch rc trn mn hnh</strong>, nhn ci g cng d chu hn hn.</p>
<h2 id="heading-cac-extension-chan-quang-cao-pho-bien">Cc extension chn qung co ph bin</h2>
<p>Di y l nhng extension c nhiu ngi dng ph thng la chn v <strong>d ci  d dng  hiu qu tt</strong>.</p>
<h2 id="heading-1-ublock-origin-lite-nhe-manh-va-mien-phi">1. uBlock Origin Lite  Nh, mnh v min ph</h2>
<p><strong>uBlock Origin Lite</strong> l mt trong nhng extension chn qung co YouTube v website c nh gi cao nht hin nay.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767515268274/40802e64-cbbe-4512-ab2e-535ae1ab17db.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-uu-diem">u im:</h3>
<ul>
<li><p>Chn qung co YouTube rt hiu qu</p>
</li>
<li><p>Chn banner, pop-up trn hu ht website</p>
</li>
<li><p>Rt nh, khng lm chm my</p>
</li>
<li><p>Hon ton min ph, khng qung co</p>
</li>
</ul>
<h3 id="heading-nhuoc-diem">Nhc im:</h3>
<ul>
<li><p>Giao din nng cao hi kh hiu vi ngi mi</p>
</li>
<li><p>Tuy nhin, dng mc nh l  tt</p>
</li>
</ul>
<p>👉 Ph hp cho: ngi dng ph thng mun ci mt ln, dng lu di.</p>
<p><strong>Cch ci t:</strong> <a target="_blank" href="https://chromewebstore.google.com/detail/ublock-origin-lite/ddkjiahejlhfcafbddmgiahcphecmpfh?hl=en">Truy cp vo ca hng chrome</a>  Thm vo chrome l xong.</p>
<h2 id="heading-2-adblock-de-dung-quen-thuoc">2. AdBlock  D dng, quen thuc</h2>
<p><strong>AdBlock</strong> l ci tn quen thuc vi rt nhiu ngi mi bt u dng extension chn qung co.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767515319095/a39f3a4c-f4df-4ae5-929f-929a77b294de.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-uu-diem-1">u im:</h3>
<ul>
<li><p>Ci t nhanh, giao din thn thin</p>
</li>
<li><p>Chn qung co YouTube v website kh tt</p>
</li>
<li><p>Ph hp vi ngi khng rnh cng ngh</p>
</li>
</ul>
<h3 id="heading-nhuoc-diem-1">Nhc im:</h3>
<ul>
<li><p>C tnh nng qung co chp nhn c (c th tt)</p>
</li>
<li><p>Hi tn ti nguyn hn uBlock Origin Lite</p>
</li>
</ul>
<p>👉 Ph hp cho: ngi dng ph thng, thch s n gin.</p>
<p><strong>Cch ci t:</strong> <a target="_blank" href="https://chromewebstore.google.com/detail/adblock-%E2%80%94-block-ads-acros/gighmmpiobklfepjocnamgkkbiglidom?hl=en">Truy cp vo ca hng chrome</a>  Thm vo chrome l xong.</p>
<h2 id="heading-3-adguard-chan-quang-cao-toan-dien">3. AdGuard  Chn qung co ton din</h2>
<p><strong>AdGuard</strong> khng ch l extension m cn c phn mm ring cho my tnh v in thoi.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1767515387367/43bfbdec-ac7e-4a67-ba3b-4d5fbe336079.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-uu-diem-2">u im:</h3>
<ul>
<li><p>Chn qung co YouTube hiu qu</p>
</li>
<li><p>Chn qung co trn website rt tt</p>
</li>
<li><p>C thm tnh nng bo v quyn ring t</p>
</li>
</ul>
<h3 id="heading-nhuoc-diem-2">Nhc im:</h3>
<ul>
<li><p>Phin bn y  cn tr ph</p>
</li>
<li><p>Extension min ph c gii hn</p>
</li>
</ul>
<p>👉 Ph hp cho: ngi mun chn qung co c YouTube ln website  mc cao hn.</p>
<p><strong>Cch ci t:</strong> <a target="_blank" href="https://chromewebstore.google.com/detail/adguard-adblocker/bgnkhhnnamicmpeenaelnjfhikgbkllg?hl=en">Truy cp vo ca hng chrome</a>  Thm vo chrome l xong.</p>
<h2 id="heading-khong-chi-youtube-extension-con-chan-quang-cao-tren-website-rat-hieu-qua">Khng ch YouTube  Extension cn chn qung co trn website rt hiu qu</h2>
<p>Bn cnh YouTube, cc extension chn qung co k trn cn hot ng cc k tt trn <strong>cc website c cha qung co</strong> nh trang tin, blog, din n</p>
<p>Chng c th:</p>
<ul>
<li><p>n banner qung co hai bn trang</p>
</li>
<li><p>Chn pop-up bt ln bt ng</p>
</li>
<li><p>Loi b qung co che ni dung</p>
</li>
<li><p>Ngn video qung co t chy</p>
</li>
</ul>
<p>Nhiu ngi sau khi ci extension chn qung co mi nhn ra rng <strong>lt web cng c th sch s v d chu n vy</strong>.</p>
<h2 id="heading-youtube-dang-chong-adblock-nhu-the-nao">YouTube ang chng adblock nh th no?</h2>
<p>Thi gian gn y, YouTube  bt u <strong>sit cht vic dng adblock</strong>. C th bn  tng thy thng bo yu cu tt trnh chn qung co trc khi xem video.</p>
<p><strong>Nhng g YouTube ang lm:</strong></p>
<ul>
<li><p>Pht hin trnh duyt ang dng adblock</p>
</li>
<li><p>Hin th cnh bo</p>
</li>
<li><p>Tm chn pht video</p>
</li>
<li><p>Gi  ng k YouTube Premium</p>
</li>
</ul>
<p>iu ny khin nhiu ngi lo lng rng extension chn qung co YouTube s ht thi. Tuy nhin, thc t l:</p>
<ul>
<li><p>Mt s extension vn hot ng n</p>
</li>
<li><p>Cn cp nht thng xuyn</p>
</li>
<li><p>Khng phi lc no cng chn c 100%</p>
</li>
</ul>
<h2 id="heading-dung-extension-chan-quang-cao-co-vi-pham-khong">Dng extension chn qung co c vi phm khng?</h2>
<p>Cu hi ny c rt nhiu ngi quan tm.</p>
<ul>
<li><p>V php lut: <strong>khng vi phm</strong></p>
</li>
<li><p>V iu khon YouTube: <strong>khng c khuyn khch</strong></p>
</li>
<li><p>V o c: ty quan im mi ngi</p>
</li>
</ul>
<p>Nu bn yu thch mt knh YouTube hay website no , bn c th <strong>tt chn qung co ring cho h</strong>  ng h  hu ht extension u h tr whitelist rt d dng.</p>
<h2 id="heading-meo-dung-extension-chan-quang-cao-on-dinh-hon">Mo dng extension chn qung co n nh hn</h2>
<p> trnh li v dng lu di, bn c th p dng vi mo nh sau:</p>
<ul>
<li><p>Lun cp nht extension ln phin bn mi</p>
</li>
<li><p>Khng ci nhiu extension chn qung co cng lc</p>
</li>
<li><p>Khi b chn xem video, th tt/bt li extension</p>
</li>
<li><p>Whitelist nhng website hoc knh bn mun ng h</p>
</li>
</ul>
<h2 id="heading-co-nen-dung-youtube-premium-thay-cho-adblock">C nn dng YouTube Premium thay cho adblock?</h2>
<p>YouTube Premium l gii php chnh thng:</p>
<ul>
<li><p>Khng c qung co</p>
</li>
<li><p>Pht video nn</p>
</li>
<li><p>Ti video offline</p>
</li>
</ul>
<p>Tuy nhin, n ch b hin th qung co trn Youtube. Vi ngi dng ph thng, <strong>extension chn qung co YouTube v website</strong> vn l la chn tit kim v linh hot hn.</p>
<p>Qung co trn YouTube v website ngy cng nhiu l iu kh trnh khi, nhng bn hon ton c th <strong>ch ng ci thin tri nghim</strong> bng cch s dng cc extension chn qung co ph hp. Vi ngi dng ph thng, ch cn mt cng c nh <strong>uBlock Origin Lite, AdBlock hoc AdGuard</strong> l   dng hng ngy ri.</p>
<p>Quan trng nht vn l dng mt cch hp l: <strong>xem thoi mi hn, lt web gn gng hn</strong>, nhng ng qun ng h nhng nh sng to ni dung m bn yu thch khi c th.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/extension-chan-quang-cao-youtube-website</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/extension-chan-quang-cao-youtube-website</guid><category><![CDATA[extension]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[useEffectEvent trong React 19]]></title><description><![CDATA[<p>React 19.2 chnh thc gii thiu <strong>useEffectEvent</strong>, mt hook mi gip gii quyt trit  vn  <strong>stale closure</strong>  th  khin khng t developer au u sut nhiu nm khi lm vic vi useEffect, event listener hay subscription.</p>
<p>Hook ny cho php bn vit code theo ng <em>mental model</em> ca React: <strong>render l render, event l event</strong>, khng cn phi lch lut dependency array na.</p>
<h2 id="heading-useeffectevent-la-gi">useEffectEvent l g?</h2>
<p><strong>useEffectEvent</strong> l mt hook mi trong React 19.2, cho php bn to ra mt <strong>event handler n nh</strong> (stable reference) nhng <strong>lun truy cp c state v props mi nht</strong>.</p>
<p>Ni cch khc:</p>
<ul>
<li><p>Khng b stale closure</p>
</li>
<li><p>Khng cn thm dependency vo useEffect</p>
</li>
<li><p>Khng cn useCallback + dependency array phc tp</p>
</li>
<li><p>Code d c, ng logic hn</p>
</li>
</ul>
<h2 id="heading-stale-closure-la-gi">Stale Closure l g?</h2>
<p>Trc khi hiu v sao useEffectEvent xn n vy, mnh cn nhn li vn  c.</p>
<h3 id="heading-vi-du-quen-thuoc-voi-useeffect">V d quen thuc vi useEffect</h3>
<pre><code class="lang-javascript">useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-keyword">const</span> id = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(count);
  }, <span class="hljs-number">1000</span>);

  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">clearInterval</span>(id);
}, []);
</code></pre>
<p>iu g xy ra?</p>
<ul>
<li><p><code>count</code> lun l <strong>gi tr ban u</strong></p>
</li>
<li><p>V dependency array rng <code>[]</code></p>
</li>
<li><p>Callback trong <code>setInterval</code> b <strong>ng bng state</strong> (stale closure)</p>
</li>
</ul>
<p>Cch sa trc y</p>
<ul>
<li><p>Thm <code>count</code> vo dependency  interval b reset lin tc</p>
</li>
<li><p>Dng <code>useRef</code>  code kh c</p>
</li>
<li><p>Dng <code>useCallback</code>  dependency chng dependency</p>
</li>
</ul>
<p><strong>Khng hp l, khng ng   ban u</strong>.</p>
<h2 id="heading-useeffectevent-giai-quyet-chuyen-nay-nhu-the-nao">useEffectEvent gii quyt chuyn ny nh th no?</h2>
<h3 id="heading-vi-du-voi-useeffectevent">V d vi useEffectEvent</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { useEffect, useEffectEvent } <span class="hljs-keyword">from</span> <span class="hljs-string">"react"</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Counter</span>(<span class="hljs-params">{ count }</span>) </span>{
  <span class="hljs-keyword">const</span> logCount = useEffectEvent(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-built_in">console</span>.log(count);
  });

  useEffect(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">const</span> id = <span class="hljs-built_in">setInterval</span>(<span class="hljs-function">() =&gt;</span> {
      logCount();
    }, <span class="hljs-number">1000</span>);

    <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">clearInterval</span>(id);
  }, []);

  <span class="hljs-keyword">return</span> <span class="hljs-literal">null</span>;
}
</code></pre>
<h3 id="heading-dieu-gi-khac-biet-la-gi">iu g khc bit l g?</h3>
<ul>
<li><p><code>logCount</code> <strong>khng thay i reference</strong></p>
</li>
<li><p>Nhng bn trong n lun thy <code>count</code> mi nht</p>
</li>
<li><p><code>useEffect</code> khng cn dependency</p>
</li>
<li><p>Khng reset interval</p>
</li>
<li><p>Code c pht hiu lin, khng hack no</p>
</li>
</ul>
<h2 id="heading-mental-model-moi-reactive-vs-non-reactive-logic">Mental Model mi: Reactive vs Non-reactive logic</h2>
<p>React 19.2 chia logic thnh 2 loi r rng:</p>
<h3 id="heading-reactive-logic-phan-ung-voi-render">Reactive logic (phn ng vi render)</h3>
<ul>
<li><p>useEffect</p>
</li>
<li><p>dependency array</p>
</li>
<li><p>chy li khi props/state thay i</p>
</li>
</ul>
<h3 id="heading-non-reactive-logic-event-logic">Non-reactive logic (event logic)</h3>
<ul>
<li><p>click</p>
</li>
<li><p>timer</p>
</li>
<li><p>websocket</p>
</li>
<li><p>analytics</p>
</li>
<li><p>subscription callback</p>
</li>
</ul>
<p>👉 <strong>useEffectEvent dnh cho loi th 2</strong></p>
<h2 id="heading-so-sanh-useeffectevent-vs-useeffect-vs-usecallback">So snh: useEffectEvent vs useEffect vs useCallback</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Hook</td><td>Reference n nh</td><td>Truy cp state mi</td><td>Dependency array</td><td>Mc ch chnh</td></tr>
</thead>
<tbody>
<tr>
<td>useEffect</td><td></td><td></td><td>Bt buc</td><td>Side effects</td></tr>
<tr>
<td>useCallback</td><td></td><td> (nu deps sai)</td><td>Phc tp</td><td>Memo function</td></tr>
<tr>
<td><strong>useEffectEvent</strong></td><td></td><td></td><td></td><td>Event logic</td></tr>
</tbody>
</table>
</div><p>👉 useEffectEvent <strong>khng thay th useEffect</strong>, m b sung ng ch React cn thiu.</p>
<h2 id="heading-use-case-thuc-te-nen-dung-useeffectevent">Use case thc t nn dng useEffectEvent</h2>
<h3 id="heading-1-event-listener-window-document">1. Event Listener (window, document)</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> onScroll = useEffectEvent(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">console</span>.log(<span class="hljs-built_in">window</span>.scrollY);
});

useEffect(<span class="hljs-function">() =&gt;</span> {
  <span class="hljs-built_in">window</span>.addEventListener(<span class="hljs-string">"scroll"</span>, onScroll);
  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> <span class="hljs-built_in">window</span>.removeEventListener(<span class="hljs-string">"scroll"</span>, onScroll);
}, []);
</code></pre>
<p>Khng lo stale state, khng cn deps.</p>
<h3 id="heading-2-websocket-subscription">2. WebSocket / Subscription</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> onMessage = useEffectEvent(<span class="hljs-function">(<span class="hljs-params">msg</span>) =&gt;</span> {
  setMessages(<span class="hljs-function"><span class="hljs-params">prev</span> =&gt;</span> [...prev, msg]);
});

useEffect(<span class="hljs-function">() =&gt;</span> {
  socket.on(<span class="hljs-string">"message"</span>, onMessage);
  <span class="hljs-keyword">return</span> <span class="hljs-function">() =&gt;</span> socket.off(<span class="hljs-string">"message"</span>, onMessage);
}, []);
</code></pre>
<h3 id="heading-3-analytics-logging">3. Analytics / Logging</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> trackClick = useEffectEvent(<span class="hljs-function">() =&gt;</span> {
  analytics.track(<span class="hljs-string">"click"</span>, { userId });
});
</code></pre>
<p>Tracking lun dng userId mi nht, khng cn re-register event.</p>
<h2 id="heading-nhung-dieu-khong-nen-lam">Nhng iu KHNG nn lm</h2>
<h3 id="heading-goi-useeffectevent-trong-dieu-kien">Gi useEffectEvent trong iu kin</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (condition) {
  useEffectEvent(<span class="hljs-function">() =&gt;</span> {});
}
</code></pre>
<p>👉 Hook rule vn p dng, <strong>tuyt i trnh lm iu ny</strong>.</p>
<h3 id="heading-dung-useeffectevent-thay-cho-useeffect">Dng useEffectEvent thay cho useEffect</h3>
<pre><code class="lang-javascript"><span class="hljs-comment">// Sai mc ch</span>
useEffectEvent(<span class="hljs-function">() =&gt;</span> {
  fetchData();
});
</code></pre>
<p>👉 useEffectEvent <strong>khng chy t ng</strong>, n ch l function.</p>
<h2 id="heading-useeffectevent-va-tuong-lai-cua-react">useEffectEvent v tng lai ca React</h2>
<p>useEffectEvent gip:</p>
<ul>
<li><p>Gim eslint-disable</p>
</li>
<li><p>t bug do dependency</p>
</li>
<li><p>Code gn vi JS thun hn</p>
</li>
<li><p>Chun b cho React Compiler &amp; concurrent features</p>
</li>
</ul>
<p>Nhiu kh nng trong tng lai, <strong>React s khuyn khch tch r render logic v event logic</strong> bng hook ny.</p>
<h2 id="heading-tong-ket">Tng kt</h2>
<p><strong>useEffectEvent</strong> khng phi l mt hook cho vui, m l mt bc tin rt ln trong trit l thit k ca React. N gii quyt tn gc vn  stale closure, gip code <strong>d c hn, ng   hn v t bug hn</strong>.</p>
<p>Nu bn:</p>
<ul>
<li><p>Hay vit event listener</p>
</li>
<li><p>Hay lm timer, socket, analytics</p>
</li>
<li><p>Ght dependency array</p>
</li>
</ul>
<p>👉 useEffectEvent chc chn l th bn nn p dng ngay t by gi.</p>
<h2 id="heading-tai-lieu-tham-khao">Ti liu tham kho</h2>
<ul>
<li><p>React Blog: <a target="_blank" href="https://react.dev/blog/2025/10/01/react-19-2#use-effect-event">https://react.dev/blog/2025/10/01/react-19-2#use-effect-event</a></p>
</li>
<li><p>React Reference: <a target="_blank" href="https://react.dev/reference/react/useEffectEvent">https://react.dev/reference/react/useEffectEvent</a></p>
</li>
</ul>
]]></description><link>https://blog.thanhnamnguyen.dev/useeffectevent-trong-react-19</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/useeffectevent-trong-react-19</guid><category><![CDATA[React]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Cách làm dark mode “chuẩn chỉnh” với CSS và JavaScript]]></title><description><![CDATA[<blockquote>
<p>Dark mode  tr thnh mt phn gn nh <strong>phi c</strong> trong mi website hin i. Khng ch gip giao din trng chuyn nghip hn, dark mode cn gim mi mt khi c ni dung ban m v tit kim pin cho cc thit b mn hnh OLED.</p>
</blockquote>
<p>Trong bi vit ny, mnh s chia s cch <strong>lm dark mode chun chnh vi CSS v JavaScript</strong>.</p>
<h2 id="heading-dark-mode-la-gi-va-tai-sao-quan-trong">Dark Mode l g v ti sao quan trng?</h2>
<p>Dark mode (ch  ti) l giao din nn ti vi ch sng, gip:</p>
<ul>
<li><p>Gim nh sng xanh  t mi mt</p>
</li>
<li><p>Tp trung hn khi c</p>
</li>
<li><p>Tit kim pin</p>
</li>
<li><p>Website trng xn hn nhiu</p>
</li>
<li><p>Ngi dng ch ng chn theme ph hp</p>
</li>
</ul>
<p>Vic build dark mode bng <strong>CSS v JavaScript</strong> rt linh hot v n gin.</p>
<h3 id="heading-buoc-1-chuan-bi-css-variables-cho-theme">Bc 1: Chun b CSS Variables cho theme</h3>
<p>Cch n gin nht  to dark mode l s dng <strong>CSS Variables</strong>.</p>
<p><strong>V d:</strong></p>
<pre><code class="lang-css"><span class="hljs-comment">/* Light theme (default) */</span>
<span class="hljs-selector-pseudo">:root</span> {
  <span class="hljs-attribute">--bg-color</span>: <span class="hljs-number">#ffffff</span>;
  <span class="hljs-attribute">--text-color</span>: <span class="hljs-number">#222222</span>;
  <span class="hljs-attribute">--primary-color</span>: <span class="hljs-number">#007bff</span>;
}

<span class="hljs-comment">/* Dark theme */</span>
<span class="hljs-selector-class">.dark</span> {
  <span class="hljs-attribute">--bg-color</span>: <span class="hljs-number">#121212</span>;
  <span class="hljs-attribute">--text-color</span>: <span class="hljs-number">#e0e0e0</span>;
  <span class="hljs-attribute">--primary-color</span>: <span class="hljs-number">#4dabf7</span>;
}

<span class="hljs-selector-tag">body</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-built_in">var</span>(--bg-color);
  <span class="hljs-attribute">color</span>: <span class="hljs-built_in">var</span>(--text-color);
}
</code></pre>
<p><strong>Li ch khi dng CSS Variables:</strong></p>
<ul>
<li><p>D bo tr</p>
</li>
<li><p>D m rng cho multiple themes</p>
</li>
<li><p>Khng cn sa nhiu class CSS</p>
</li>
</ul>
<h3 id="heading-buoc-2-them-nut-chuyen-doi-toggle-button">Bc 2: Thm nt chuyn i (Toggle Button)</h3>
<p>Bn cn mt toggle nh  ngi dng i theme.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"theme-toggle"</span>&gt;</span>Toggle Dark Mode<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<h3 id="heading-buoc-3-viet-javascript-de-battat-dark-mode">Bc 3: Vit JavaScript  bt/tt Dark Mode</h3>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> toggleBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"theme-toggle"</span>);
<span class="hljs-keyword">const</span> body = <span class="hljs-built_in">document</span>.body;

toggleBtn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  body.classList.toggle(<span class="hljs-string">"dark"</span>);
});
</code></pre>
<p>Nh vy l bn  build c dark mode chy ngon lnh.</p>
<h3 id="heading-buoc-4-luu-trang-thai-dark-mode-bang-localstorage">Bc 4: Lu trng thi Dark Mode bng localStorage</h3>
<p>Nhiu bn to c dark mode nhng qun mt lu trng thi, khin khi reload trang theme b reset. iu ny gy kh chu cho ngi dng.</p>
<p>Cch lu trng thi bng JavaScript:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">const</span> body = <span class="hljs-built_in">document</span>.body;
<span class="hljs-keyword">const</span> toggleBtn = <span class="hljs-built_in">document</span>.getElementById(<span class="hljs-string">"theme-toggle"</span>);

<span class="hljs-comment">// Load theme khi trang m</span>
<span class="hljs-keyword">const</span> savedTheme = <span class="hljs-built_in">localStorage</span>.getItem(<span class="hljs-string">"theme"</span>);

<span class="hljs-keyword">if</span> (savedTheme === <span class="hljs-string">"dark"</span>) {
  body.classList.add(<span class="hljs-string">"dark"</span>);
}

toggleBtn.addEventListener(<span class="hljs-string">"click"</span>, <span class="hljs-function">() =&gt;</span> {
  body.classList.toggle(<span class="hljs-string">"dark"</span>);

  <span class="hljs-comment">// Lu theme</span>
  <span class="hljs-keyword">if</span> (body.classList.contains(<span class="hljs-string">"dark"</span>)) {
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">"theme"</span>, <span class="hljs-string">"dark"</span>);
  } <span class="hljs-keyword">else</span> {
    <span class="hljs-built_in">localStorage</span>.setItem(<span class="hljs-string">"theme"</span>, <span class="hljs-string">"light"</span>);
  }
});
</code></pre>
<p>Khi reload trang  theme vn gi nguyn.</p>
<h3 id="heading-buoc-5-tu-dong-nhan-dark-mode-tu-he-dieu-hanh">Bc 5: T ng nhn dark mode t h iu hnh</h3>
<p>Nhiu h iu hnh (Android, iOS, Windows, macOS) c dark mode system-level.</p>
<p>Bn c th ng b theo h iu hnh bng CSS:</p>
<pre><code class="lang-css"><span class="hljs-keyword">@media</span> (<span class="hljs-attribute">prefers-color-scheme:</span> dark) {
  <span class="hljs-selector-pseudo">:root</span> {
    <span class="hljs-attribute">--bg-color</span>: <span class="hljs-number">#121212</span>;
    <span class="hljs-attribute">--text-color</span>: <span class="hljs-number">#e0e0e0</span>;
  }
}
</code></pre>
<p>Hoc bng JS:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">if</span> (<span class="hljs-built_in">window</span>.matchMedia(<span class="hljs-string">"(prefers-color-scheme: dark)"</span>).matches) {
  <span class="hljs-built_in">document</span>.body.classList.add(<span class="hljs-string">"dark"</span>);
}
</code></pre>
<p>Kt hp localStorage + system theme = tri nghim cc mt.</p>
<h2 id="heading-tips-giup-dark-mode-cua-ban-chuan-ux">Tips gip Dark Mode ca bn chun UX</h2>
<h3 id="heading-1-dam-bao-do-tuong-phan-contrast-chu-du-cao">1. m bo  tng phn (contrast) ch  cao</h3>
<p><strong>Dng tool kim tra contrast:</strong> <a target="_blank" href="https://webaim.org/resources/contrastchecker/">https://webaim.org/resources/contrastchecker/</a></p>
<h3 id="heading-2-dung-dung-pure-black-000">2. ng dng pure black (#000)</h3>
<p>D gy chi  Dng #121212 hoc #1a1a1a.</p>
<h3 id="heading-3-chu-y-hinh-anh">3. Ch  hnh nh</h3>
<p>Vi nh PNG:</p>
<ul>
<li><p>Dng filter invert nu cn</p>
</li>
<li><p>To 2 phin bn light/dark cho logo</p>
</li>
</ul>
<p>V d:</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.dark</span> <span class="hljs-selector-tag">img</span><span class="hljs-selector-class">.logo</span> {
  <span class="hljs-attribute">filter</span>: <span class="hljs-built_in">brightness</span>(<span class="hljs-number">0</span>) <span class="hljs-built_in">invert</span>(<span class="hljs-number">1</span>);
}
</code></pre>
<h3 id="heading-4-dung-quen-setting-theme-color-cho-seo">4. ng qun setting theme-color cho SEO</h3>
<p>Chrome s i mu thanh mobile browser.</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"theme-color"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"#121212"</span> <span class="hljs-attr">media</span>=<span class="hljs-string">"(prefers-color-scheme: dark)"</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"theme-color"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"#ffffff"</span> <span class="hljs-attr">media</span>=<span class="hljs-string">"(prefers-color-scheme: light)"</span>&gt;</span>
</code></pre>
<h3 id="heading-5-khong-toggle-bang-css-alone-neu-muon-luu-theme">5. Khng toggle bng CSS alone nu mun lu theme</h3>
<p>Nu khng dng JS  khng lu c trng thi.</p>
<p>Dark mode khng h kh. Ch cn vi dng CSS + JavaScript l website ca bn  c thm mt tnh nng cc k hin i v hu ch.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/cach-build-dark-mode-chuan-chinh-bang-css-javascript</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/cach-build-dark-mode-chuan-chinh-bang-css-javascript</guid><category><![CDATA[CSS]]></category><category><![CDATA[JavaScript]]></category><category><![CDATA[dark mode]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[TailwindCSS có thực sự tốt hơn CSS truyền thống?]]></title><description><![CDATA[<blockquote>
<p>TailwindCSS ni ln nh mt cng c CSS mnh m da trn utility classes. Nhng liu n c thc s tt hn CSS truyn thng? Cng mnh c bi vit ny  a ra la chn ph hp cho d n ca bn nh.</p>
</blockquote>
<h2 id="heading-gioi-thieu">Gii thiu</h2>
<p>Nu bn l frontend developer, chc chn bn  tng nghe cu hi quen thuc: <strong>TailwindCSS c thc s tt hn CSS truyn thng khng?</strong></p>
<p>Mt bn l <strong>CSS thun</strong> quen thuc  n gin, r rng, khng ph thuc th vin. Mt bn l <strong>TailwindCSS</strong>  utility-first, class di ngong trong html nhng li gip code cc nhanh.</p>
<p>C hai u c u im ln im hn h, v th v hn, vic chn ng cng c c th thay i hon ton tc  pht trin v tri nghim khi coding.</p>
<h2 id="heading-tailwindcss-la-gi">TailwindCSS l g?</h2>
<p>TailwindCSS l mt CSS framework theo hng <em>utility-first</em>, ngha l thay v vit CSS ring cho tng component, bn s kt hp nhiu class nh  to ra giao din.</p>
<p><strong>V d:</strong></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"px-4 py-2 bg-blue-500 text-white rounded-md"</span>&gt;</span>
  Click me
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p>Nghe c v hi ri mt? Nhng phi cng nhn n cc nhanh, v rt d ti s dng.</p>
<h2 id="heading-css-truyen-thong-la-gi">CSS truyn thng l g?</h2>
<p>CSS truyn thng l cch vit style thun ty dnh cho tng component, file, hoc global stylesheet.</p>
<p><strong>V d:</strong></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn-primary"</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-class">.btn-primary</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">8px</span> <span class="hljs-number">16px</span>;
  <span class="hljs-attribute">background-color</span>: <span class="hljs-number">#3b82f6</span>;
  <span class="hljs-attribute">color</span>: white;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">6px</span>;
}
</code></pre>
<p>R rng hn, tch bch hn, v d c hn i vi ngi mi.</p>
<h2 id="heading-so-sanh-tailwindcss-vs-css-truyen-thong">So snh TailwindCSS vs CSS truyn thng</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Tiu ch</td><td><strong>TailwindCSS</strong></td><td><strong>CSS Truyn Thng</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Tc  pht trin</strong></td><td>Rt nhanh, khng cn to file CSS, khng phi t tn class</td><td>Chm hn v phi to class, vit CSS v t chc code</td></tr>
<tr>
<td><strong> phc tp khi t tn (Naming)</strong></td><td>Khng cn t tn class  trnh BEM/OOCSS</td><td>Cn t tn class  d ri nu d n ln</td></tr>
<tr>
<td><strong>Kh nng c code</strong></td><td>HTML hi ri v nhiu class utility</td><td>HTML sch s, d c hn</td></tr>
<tr>
<td><strong>Kh nng bo tr</strong></td><td>Tt nu bit dng <code>@apply</code>, nhng HTML c th di</td><td>Rt tt, style tch bit nn d tm, d sa</td></tr>
<tr>
<td><strong>Hiu sut</strong></td><td>Nh, purge class khng dng, ti u tt</td><td>D b phnh to nu khng qun l tt</td></tr>
<tr>
<td><strong>Tnh linh hot</strong></td><td>Tt khi theo design system, nhng custom su hi kh</td><td>Rt linh hot, khng b gii hn bi framework</td></tr>
<tr>
<td><strong>Kh nng ti s dng</strong></td><td>D ti s dng bng component + <code>@apply</code></td><td>Ti s dng d thng qua class &amp; file CSS</td></tr>
<tr>
<td><strong>Tip cn cho ngi mi</strong></td><td>Ban u hi chong nhng d quen nu thc hnh nhiu</td><td>Cn hc su v cascade, specificity</td></tr>
<tr>
<td><strong>Ph hp vi d n nh</strong></td><td>Ph hp v build cc nhanh</td><td>Hon ton c nhng tn thi gian hn</td></tr>
<tr>
<td><strong>Ph hp vi d n ln</strong></td><td>Tt nhng c th gy ri nu khng c quy tc</td><td>Rt tt nh tch bit cu trc &amp; style</td></tr>
<tr>
<td><strong>Lm vic vi React / Next.js</strong></td><td>Siu hp, tng tc  dev, c sn nhiu th vin UI nh shadcn/ui</td><td>Vn n, nhng chm hn</td></tr>
<tr>
<td><strong>Kh nng ty bin theme</strong></td><td>Ngon, nh <code>tailwind.config.js</code> (v3) hoc trong file global.css (v4)</td><td>Phi t tay setup hoc dng SCSS/variables</td></tr>
<tr>
<td><strong>Hc CSS gc</strong></td><td>Bt buc phi c kin thc nn, Tailwind ch chy trn nn CSS</td><td>Bt buc hiu, gip nm vng k thut hn</td></tr>
</tbody>
</table>
</div><h2 id="heading-vay-tailwindcss-co-thuc-su-tot-hon-css-truyen-thong-khong">Vy TailwindCSS c thc s tt hn CSS truyn thng khng?</h2>
<blockquote>
<p><strong>Cu tr li:</strong> Ty d n, ty team, ty phong cch ca bn.</p>
</blockquote>
<p><strong>TailwindCSS l la chn tuyt vi khi:</strong></p>
<ul>
<li><p>Bn mun code nhanh, cc nhanh</p>
</li>
<li><p>Bn xy prototyping hoc MVP</p>
</li>
<li><p>Team cn thng nht UI trn ton h thng</p>
</li>
<li><p>Bn lm vic vi React, Vue, Next.js, Laravel</p>
</li>
<li><p>Bn khng mun ngh qu nhiu v t tn class</p>
</li>
</ul>
<p><strong>CSS truyn thng l la chn tt hn khi:</strong></p>
<ul>
<li><p>Bn lm d n ln, nhiu component phc tp</p>
</li>
<li><p>Bn mun HTML sch s, d c</p>
</li>
<li><p>Team quen vi SCSS, BEM hoc OOCSS</p>
</li>
<li><p>Bn lm vic vi designer thch sng to</p>
</li>
<li><p>Bn mun kim sot CSS t gc n ngn</p>
</li>
</ul>
<h2 id="heading-mot-so-vi-du-thuc-te">Mt s v d thc t</h2>
<p><strong>Styling button dng TailwindCSS</strong></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"px-4 py-2 bg-blue-500 text-white rounded-md shadow hover:bg-blue-600"</span>&gt;</span>
  Mua ngay
<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<p><strong>Styling button dng CSS truyn thng</strong></p>
<pre><code class="lang-xml"><span class="hljs-tag">&lt;<span class="hljs-name">button</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"btn-primary"</span>&gt;</span>Mua ngay<span class="hljs-tag">&lt;/<span class="hljs-name">button</span>&gt;</span>
</code></pre>
<pre><code class="lang-css"><span class="hljs-selector-class">.btn-primary</span> {
  <span class="hljs-attribute">padding</span>: <span class="hljs-number">8px</span> <span class="hljs-number">16px</span>;
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#3b82f6</span>;
  <span class="hljs-attribute">color</span>: <span class="hljs-number">#fff</span>;
  <span class="hljs-attribute">border-radius</span>: <span class="hljs-number">6px</span>;
  <span class="hljs-attribute">box-shadow</span>: <span class="hljs-number">0</span> <span class="hljs-number">1px</span> <span class="hljs-number">4px</span> <span class="hljs-built_in">rgba</span>(<span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0</span>, <span class="hljs-number">0.2</span>);
}
<span class="hljs-selector-class">.btn-primary</span><span class="hljs-selector-pseudo">:hover</span> {
  <span class="hljs-attribute">background</span>: <span class="hljs-number">#2563eb</span>;
}
</code></pre>
<p>👉 CSS truyn thng c d hn.<br />👉 TailwindCSS dng nhanh hn.</p>
<h2 id="heading-loi-ket">Li kt</h2>
<p>TailwindCSS <strong>khng hn tt hn</strong> CSS truyn thng, v CSS truyn thng cng <strong>khng h c l s</strong>. <strong>iu quan trng l:</strong></p>
<ul>
<li><p>Bn ang lm d n g</p>
</li>
<li><p>Team ca bn quen vi cng c no</p>
</li>
<li><p>Bn u tin tc  hay tnh r rng</p>
</li>
</ul>
<p>D chn ci no, iu quan trng nht vn l <strong>hiu CSS tht s</strong>, v mi framework ch l lp tin ch nm trn nn tng ct li m thi.</p>
<h2 id="heading-mot-so-link-tham-khao-hay-ho-danh-cho-ban">Mt s link tham kho hay ho dnh cho bn</h2>
<ul>
<li><p><a target="_blank" href="https://tailwindcss.com/">https://tailwindcss.com</a></p>
</li>
<li><p><a target="_blank" href="https://css-tricks.com/">https://css-tricks.com</a></p>
</li>
<li><p><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/CSS">https://developer.mozilla.org/en-US/docs/Web/CSS</a></p>
</li>
</ul>
]]></description><link>https://blog.thanhnamnguyen.dev/tailwindcss-co-thuc-su-tot-hon-css-truyen-thong</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/tailwindcss-co-thuc-su-tot-hon-css-truyen-thong</guid><category><![CDATA[Tailwind CSS]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Cloudflare R2 Storage – Giải pháp lưu trữ không phí egress dành cho developer]]></title><description><![CDATA[<h2 id="heading-1-cloudflare-r2-storage-la-gi">1. Cloudflare R2 Storage l g?</h2>
<p>Cloudflare R2 l dch v <strong>object storage</strong> do <strong>Cloudflare</strong> pht trin, c thit k nh mt gii php thay th cho <strong>Amazon S3</strong>, nhng <strong>khng tnh ph egress</strong> (bng thng ti d liu ra).</p>
<p>R2 c xy dng trn <strong>Workers</strong> v <strong>Durable Objects</strong>, gip cc developer truy cp v lu tr d liu quy m ln vi  tr thp, bo mt cao v chi ph cc k cnh tranh.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762877346608/9bbb5a20-a626-4147-af8d-a8dc55fb8326.jpeg" alt class="image--center mx-auto" /></p>
<p><strong>im khc bit chnh:</strong></p>
<ul>
<li><p><strong>Khng ph egress:</strong> Ti d liu ra (ra khi R2) hon ton min ph.</p>
</li>
<li><p><strong>Chi ph lu tr thp</strong></p>
</li>
<li><p><strong>Tch hp mt vi Cloudflare Workers:</strong> C th x l d liu ngay ti edge m khng cn server trung gian.</p>
</li>
<li><p><strong>API tng thch vi S3:</strong> D dng chuyn i ng dng ang dng S3 sang R2 m khng phi vit li code.</p>
</li>
</ul>
<p>Bn free cho chng ta ti tn 10GB lu tr mi thng, thay v tnh ph egress, h tnh da theo s lng c (Class B Operations) v ghi (Class A Operations) mi thng. Xem chi tit <a target="_blank" href="https://developers.cloudflare.com/r2/pricing/">ti y</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762877351223/5fa9aed3-079b-4369-bc6a-7416528880b4.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-2-kien-truc-tong-quan-cua-r2">2. Kin trc tng quan ca R2</h2>
<p><img src="https://cf-assets.www.cloudflare.com/zkvhlag99gkb/7ueoC6FVML11Wrrpr2ELlt/38ceacbacb2b5891ad12f2e52ee0b666/unnamed-1.png" alt="Cloudflare R2 means removing ridiculous fees" /></p>
<p>R2 c xy dng trn nn tng <strong>Cloudflare Edge Network</strong>  mt trong nhng mng phn phi d liu ln nht th gii, vi hn 300+ data centers ton cu.<br />Khi bn lu tr d liu ln R2, Cloudflare s:</p>
<ul>
<li><p>Phn b d liu ln h thng lu tr phn tn.</p>
</li>
<li><p>Sao chp (replicate) d liu gia nhiu vng  m bo  bn.</p>
</li>
<li><p>Cung cp truy cp trc tip thng qua API tng thch vi <strong>AWS S3 SDK</strong>.</p>
</li>
</ul>
<p>V nm trong cng h sinh thi vi <strong>Workers</strong> v <strong>Pages</strong>, R2 c th kt hp trc tip  x l file, resize nh, hoc to CDN ng ngay ti edge m khng cn gi API t bn th ba.</p>
<h2 id="heading-3-cach-su-dung-cloudflare-r2">3. Cch s dng Cloudflare R2</h2>
<h3 id="heading-31-su-dung-bang-api">3.1. S dng bng API</h3>
<p>Cloudflare R2 cung cp giao din <strong>S3-compatible API</strong>, ngha l bn c th dng bt k SDK no h tr Amazon S3  kt ni vi R2.</p>
<p><strong>V d: Kt ni R2 bng Node.js (AWS SDK v3)</strong></p>
<p>Trc ht, to Access Key t <a target="_blank" href="https://developers.cloudflare.com/r2/api/tokens/">Cloudflare Dashboard  R2  Manage API Tokens</a>.</p>
<pre><code class="lang-bash">npm install @aws-sdk/client-s3
</code></pre>
<p>Sau  cu hnh SDK:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { S3Client, PutObjectCommand } <span class="hljs-keyword">from</span> <span class="hljs-string">"@aws-sdk/client-s3"</span>;

<span class="hljs-keyword">const</span> client = <span class="hljs-keyword">new</span> S3Client({
  <span class="hljs-attr">region</span>: <span class="hljs-string">"auto"</span>,
  <span class="hljs-attr">endpoint</span>: <span class="hljs-string">"https://&lt;your-account-id&gt;.r2.cloudflarestorage.com"</span>,
  <span class="hljs-attr">credentials</span>: {
    <span class="hljs-attr">accessKeyId</span>: <span class="hljs-string">"R2_ACCESS_KEY"</span>,
    <span class="hljs-attr">secretAccessKey</span>: <span class="hljs-string">"R2_SECRET_KEY"</span>
  }
});

<span class="hljs-keyword">const</span> upload = <span class="hljs-keyword">async</span> () =&gt; {
  <span class="hljs-keyword">const</span> command = <span class="hljs-keyword">new</span> PutObjectCommand({
    <span class="hljs-attr">Bucket</span>: <span class="hljs-string">"my-r2-bucket"</span>,
    <span class="hljs-attr">Key</span>: <span class="hljs-string">"hello.txt"</span>,
    <span class="hljs-attr">Body</span>: <span class="hljs-string">"Hello Cloudflare R2!"</span>
  });

  <span class="hljs-keyword">await</span> client.send(command);
  <span class="hljs-built_in">console</span>.log(<span class="hljs-string">"File uploaded successfully!"</span>);
};

upload();
</code></pre>
<p>Tng t, bn c th dng <code>GetObjectCommand</code>, <code>ListObjectsCommand</code>, hoc <code>DeleteObjectCommand</code> y ht nh khi lm vic vi Amazon S3.</p>
<p>👉 Ton b ti liu hng dn bn c th tham kho ti <a target="_blank" href="https://developers.cloudflare.com/r2/">Cloudflare R2</a></p>
<h3 id="heading-32-su-dung-bang-giao-dien-tren-dashboard">3.2. S dng bng giao din trn dashboard</h3>
<p>Truy cp vo dashboard ca Cloudlfare v vo mc Storage &amp; databases  R2  tin hnh to bucket cng nh upload.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762877739965/d6288a3c-25d2-4603-aba2-6b06aaf6870d.jpeg" alt class="image--center mx-auto" /></p>
<h2 id="heading-4-ket-hop-r2-voi-cloudflare-workers">4. Kt hp R2 vi Cloudflare Workers</h2>
<p>im mnh nht ca R2 l kh nng tch hp trc tip vi <strong>Cloudflare Workers</strong>  gip bn x l d liu ti edge m khng cn backend truyn thng.</p>
<p>V d di y minh ha cch c file t R2 trong Worker:</p>
<pre><code class="lang-js"><span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> {
  <span class="hljs-keyword">async</span> fetch(request, env) {
    <span class="hljs-keyword">const</span> object = <span class="hljs-keyword">await</span> env.MY_BUCKET.get(<span class="hljs-string">"hello.txt"</span>);
    <span class="hljs-keyword">if</span> (!object) {
      <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Response(<span class="hljs-string">"File not found!"</span>, { <span class="hljs-attr">status</span>: <span class="hljs-number">404</span> });
    }
    <span class="hljs-keyword">return</span> <span class="hljs-keyword">new</span> Response(object.body);
  },
};
</code></pre>
<p> y, <code>env.MY_BUCKET</code> c cu hnh trong <code>wrangler.toml</code> nh sau:</p>
<pre><code class="lang-toml"><span class="hljs-section">[[r2_buckets]]</span>
<span class="hljs-attr">binding</span> = <span class="hljs-string">"MY_BUCKET"</span>
<span class="hljs-attr">bucket_name</span> = <span class="hljs-string">"my-r2-bucket"</span>
</code></pre>
<p>Khi deploy, Worker s c quyn truy cp trc tip vo bucket m khng cn gi API qua mng  gip tc  c/ghi nhanh hn rt nhiu.</p>
<h2 id="heading-5-so-sanh-cloudflare-r2-voi-amazon-s3">5. So snh Cloudflare R2 vi Amazon S3</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Tiu ch</td><td><strong>Cloudflare R2</strong></td><td><strong>Amazon S3</strong></td></tr>
</thead>
<tbody>
<tr>
<td>Ph egress</td><td>Min ph</td><td>Tnh ph (kh cao)</td></tr>
<tr>
<td>API</td><td>Tng thch S3</td><td>Native</td></tr>
<tr>
<td>Tch hp Edge</td><td>C (Workers)</td><td>Khng trc tip</td></tr>
<tr>
<td>Tc  truy cp</td><td>Cc nhanh ti Edge</td><td>Ph thuc region</td></tr>
<tr>
<td>D dng di chuyn d liu</td><td>C</td><td>C</td></tr>
<tr>
<td>Mc tiu chnh</td><td>Gim chi ph, tng hiu nng</td><td>Lu tr m my truyn thng</td></tr>
</tbody>
</table>
</div><p>R2 l tng cho developer mun ti u chi ph phn phi file tnh (nh, video, d liu JSON) hoc lm backend lu tr cho ng dng chy trn Cloudflare Workers / Pages.</p>
<h2 id="heading-6-mot-so-truong-hop-su-dung-thuc-te">6. Mt s trng hp s dng thc t</h2>
<ul>
<li><p><strong>Static file hosting:</strong> Lu nh, video, script cho web hoc ng dng di ng.</p>
</li>
<li><p><strong>Backup &amp; archival:</strong> Lu tr d liu lu di vi chi ph thp.</p>
</li>
<li><p><strong>Serverless backend:</strong> Kt hp vi Workers  to REST API cho file upload/download.</p>
</li>
<li><p><strong>AI &amp; ML storage:</strong> Lu dataset cho cc ng dng AI inferencing chy  edge.</p>
</li>
</ul>
<h2 id="heading-7-giam-sat-va-bao-mat">7. Gim st v bo mt</h2>
<p>Cloudflare cung cp cc tnh nng qun l truy cp chi tit cho R2 thng qua <strong>Access Policies</strong> v <strong>API Tokens</strong>.</p>
<p><strong>Bn c th:</strong></p>
<ul>
<li><p>Gii hn quyn <code>read/write</code> theo bucket hoc theo prefix.</p>
</li>
<li><p>Theo di log truy cp qua <strong>Cloudflare Analytics</strong>.</p>
</li>
<li><p>D dng tch hp vi <strong>Zero Trust Access</strong>  bo v endpoint ni b.</p>
</li>
</ul>
<h2 id="heading-tom-lai">Tm li</h2>
<p>Cloudflare R2 Storage l cch gip dev <strong>gim chi ph, loi b egress, v tng tc phn phi ni dung ton cu</strong>. y l gii php tuyt vi  xy dng backend serverless, h thng phn phi file, hoc nn tng d liu ln vi chi ph ti u v hiu nng vt tri.</p>
<h2 id="heading-tai-lieu-tham-khao">Ti liu tham kho</h2>
<ul>
<li><p><a target="_blank" href="https://developers.cloudflare.com/r2/">R2 Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://developers.cloudflare.com/workers/tutorials/">Cloudflare Workers + R2 Getting Started</a></p>
</li>
</ul>
]]></description><link>https://blog.thanhnamnguyen.dev/cloudflare-r2-storage-giai-phap-luu-tru-khong-phi-egress-danh-cho-developer</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/cloudflare-r2-storage-giai-phap-luu-tru-khong-phi-egress-danh-cho-developer</guid><category><![CDATA[cloudflare]]></category><category><![CDATA[Cloudflare-r2]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Rive là gì? Cứu tinh mới cho animation trong Web Development]]></title><description><![CDATA[<h2 id="heading-vi-sao-animation-luon-la-ac-mong-voi-web-dev">V sao animation lun l c mng vi web dev?</h2>
<p>Nu bn tng lm vic vi designer trn Figma, chc hn  c lc au u khi h gi mt thit k lung linh vi hng t motion, transition v hover effect Nhng khi xut sang code, tt c ch cn l hnh tnh. 😩</p>
<p>Bn bt u m CSS transitions, vit c ng <code>@keyframes</code>, hoc th dng th vin nh <strong>Framer Motion</strong>, <strong>GSAP</strong>, hay <strong>Lottie</strong>  nhng lc no cng phi nh i gia hiu nng,  mt v thi gian lm.</p>
<p>Chnh v th, <strong>Rive.app</strong> ra i  khng ch gip designer v developer ni cng ngn ng animation, m cn bin vic nhng motion vo web app tr nn n gin hn bao gi ht.</p>
<h2 id="heading-rive-la-gi">Rive l g?</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=mMpik32gkt4">https://www.youtube.com/watch?v=mMpik32gkt4</a></div>
<p> </p>
<p><strong>Rive</strong> l mt nn tng trc tuyn cho php bn <strong>thit k, to animation, v xy dng tng tc theo thi gian thc</strong>. im khc bit ca Rive so vi cc cng c khc (nh After Effects hay Lottie) l:</p>
<ul>
<li><p>N khng ch render animation, m cn cho php <strong>lp trnh logic tng tc</strong>.</p>
</li>
<li><p>Tt c c ng gi trong <strong>file</strong> <code>.riv</code> nh v ti u.</p>
</li>
</ul>
<p>Rive hot ng da trn <strong>State Machine</strong>  mt h thng cho php bn nh ngha trng thi v cch animation phn ng vi s kin ngi dng.</p>
<p><strong>V d:</strong> khi ngi dng click, hover, hay scroll  animation c th i trng thi ngay lp tc, mt m nh trong game.</p>
<h2 id="heading-vi-sao-rive-la-cuu-tinh-cua-web-dev">V sao Rive l cu tinh ca web dev?</h2>
<p>Hy th so snh quy trnh animation c v mi nh 👇</p>
<h3 id="heading-cach-truyen-thong">Cch truyn thng</h3>
<p><strong>Figma  After Effects  Lottie  JSON  React</strong></p>
<p>Mt chui di, d li v cc tn thi gian.</p>
<h3 id="heading-voi-rive">Vi Rive</h3>
<p><strong>Figma  Rive </strong> <code>.riv</code>  React hoc <strong>Rive </strong> <code>.riv</code>  React</p>
<p>Ch cn vi bc!</p>
<p>Bn import thit k t Figma vo Rive, thm motion &amp; state machine, export file <code>.riv</code>, ri nhng thng vo web app, hoc bn thit k  Rive ngay t ban u.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762514006820/8cf8eaff-8642-4721-926f-e29dac33dd7f.jpeg" alt class="image--center mx-auto" /></p>
<p>Khng cn code animation phc tp, khng cn render video  m kt qu li siu mt, nh v d bo tr.</p>
<h2 id="heading-cach-nhung-file-riv-vao-react">Cch nhng file <code>.riv</code> vo React</h2>
<p>y l phn m nhiu web dev quan tm nht! Rive cung cp <strong>SDK chnh thc cho React</strong>, gip bn d dng tch hp animation ch trong vi pht.</p>
<p>Di y l hng dn da theo <a target="_blank" href="https://rive.app/docs/runtimes/react/react">ti liu chnh thc ca Rive</a>.</p>
<h3 id="heading-buoc-1-cai-dat-thu-vien-rive-react">Bc 1: Ci t th vin Rive React</h3>
<p>Trong d n React ca bn, ci t package thng qua npm hoc yarn:</p>
<pre><code class="lang-bash">npm install @rive-app/react-canvas
</code></pre>
<p>hoc</p>
<pre><code class="lang-bash">yarn add @rive-app/react-canvas
</code></pre>
<h3 id="heading-buoc-2-chuan-bi-file-riv">Bc 2: Chun b file <code>.riv</code></h3>
<p>T <strong>Rive Editor</strong>, bn export file animation ca mnh (v d: <code>animation.riv</code>) v t vo th mc <code>public/animations</code> trong project React.</p>
<p><strong>V d:</strong></p>
<pre><code class="lang-markdown">my-app/
 public/
    animations/
        bear.riv
 src/
<span class="hljs-code">     App.jsx</span>
</code></pre>
<h3 id="heading-buoc-3-nhung-animation-vao-react-component">Bc 3: Nhng animation vo React Component</h3>
<p>Rive cung cp hai cch  render animation:</p>
<p><strong>Cch 1  Dng n gin nht:</strong></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { RiveComponent } <span class="hljs-keyword">from</span> <span class="hljs-string">'@rive-app/react-canvas'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">App</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    &lt;div style={{ width: <span class="hljs-number">400</span>, height: <span class="hljs-number">400</span> }}&gt;
      &lt;RiveComponent src=<span class="hljs-string">"/animations/bear.riv"</span> autoplay /&gt;
    &lt;/div&gt;
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> App;
</code></pre>
<ul>
<li><p><code>src</code>: ng dn n file <code>.riv</code></p>
</li>
<li><p><code>autoplay</code>: cho php animation chy t ng</p>
</li>
</ul>
<p>Cch ny rt gn gng nu bn ch mun hin th animation m khng cn logic phc tp.</p>
<p><strong>Cch 2  Dng hook useRive()  iu khin animation nng cao</strong></p>
<p>Nu bn cn <strong>iu khin animation theo event</strong> (hover, click, input, v.v.), hy dng hook <code>useRive()</code> v <code>useStateMachineInput()</code>.</p>
<p><strong>V d:</strong></p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useRive, useStateMachineInput } <span class="hljs-keyword">from</span> <span class="hljs-string">'@rive-app/react-canvas'</span>;

<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">InteractiveButton</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> STATE_MACHINE = <span class="hljs-string">"ButtonMachine"</span>;

  <span class="hljs-keyword">const</span> { rive, RiveComponent } = useRive({
    src: <span class="hljs-string">"/animations/button.riv"</span>,
    stateMachines: STATE_MACHINE,
    autoplay: <span class="hljs-literal">true</span>,
  });

  <span class="hljs-keyword">const</span> hoverInput = useStateMachineInput(rive, STATE_MACHINE, <span class="hljs-string">"hover"</span>);

  <span class="hljs-keyword">return</span> (
    &lt;div
      onMouseEnter={<span class="hljs-function">() =&gt;</span> hoverInput &amp;&amp; (hoverInput.value = <span class="hljs-literal">true</span>)}
      onMouseLeave={<span class="hljs-function">() =&gt;</span> hoverInput &amp;&amp; (hoverInput.value = <span class="hljs-literal">false</span>)}
    &gt;
      &lt;RiveComponent style={{ width: <span class="hljs-number">150</span>, height: <span class="hljs-number">150</span> }} /&gt;
    &lt;/div&gt;
  );
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> InteractiveButton;
</code></pre>
<p>👉  y, <code>STATE_MACHINE</code> tr ti State Machine bn  t tn trong Rive Editor.<br /><code>useStateMachineInput</code> cho php bn <strong>kch hot animation</strong> theo hnh ng ca ngi dng  cc k mnh m cho UI tng tc.</p>
<h3 id="heading-buoc-4-kiem-tra-va-toi-uu">Bc 4: Kim tra v ti u</h3>
<p>Bn c th m DevTools  kim tra Rive canvas ang render.<br />Ngoi ra, bn c th ti u performance bng cch:</p>
<ul>
<li><p>Ch render khi component nm trong viewport (dng Intersection Observer).</p>
</li>
<li><p>Dng animation khi tab b n (<code>document.visibilitychange</code>).</p>
</li>
</ul>
<h2 id="heading-mot-so-meo">💡 Mt s mo</h2>
<ul>
<li>Bn c th <strong>pause, play, reset</strong> animation bng cc hm nh:</li>
</ul>
<pre><code class="lang-typescript">rive.play();
rive.pause();
rive.reset();
</code></pre>
<ul>
<li>Nu mun kim tra animation hin ang  trng thi no, bn c th c t <code>rive.stateMachineInputs</code>.</li>
</ul>
<h2 id="heading-uu-diem-vuot-troi-cua-rive-trong-web-development">u im vt tri ca Rive trong Web Development</h2>
<h3 id="heading-1-animation-tuong-tac-thoi-gian-thuc">🎯 1. Animation tng tc thi gian thc</h3>
<p>Rive render bng <strong>Canvas/WebGL</strong>, gip animation mt, khng git v c th thay i ngay theo hnh ng ngi dng.</p>
<h3 id="heading-2-state-machine-cuc-manh"> 2. State Machine cc mnh</h3>
<p>Bn c th nh ngha <strong>logic iu khin animation</strong>  chng hn, khi ngi dng click, animation chuyn t trng thi idle sang active. iu m Lottie hoc CSS kh lm c.</p>
<h3 id="heading-3-de-tich-hop-voi-cac-framework-pho-bien">🧩 3. D tch hp vi cc framework ph bin</h3>
<p>Rive h tr <strong>React, Vue, Flutter, Unity, iOS, Android, C++</strong>, thm ch c Web thun. To animation mt ln  dng mi ni!</p>
<h3 id="heading-4-nhe-vector-va-scalable">💨 4. Nh, vector, v scalable</h3>
<p>File <code>.riv</code> ch vi trm KB, nh hn video hoc GIF, v c th scale m khng b v hnh.</p>
<h3 id="heading-5-designer-amp-dev-lam-viec-tron-tru">🤝 5. Designer &amp; Dev lm vic trn tru</h3>
<p>Designer ch vic export <code>.riv</code>, dev ch vic import vo project  khng cn debug code animation. Hai bn ni cng ngn ng chuyn ng.</p>
<h2 id="heading-khi-nao-nen-dung-rive">Khi no nn dng Rive?</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1762514090853/adbde17d-dba6-44e3-9020-30ebdfd63bfc.jpeg" alt class="image--center mx-auto" /></p>
<p><strong> Rive l la chn hon ho khi</strong></p>
<ul>
<li><p>Bn cn animation tng tc (hover, click, drag, input event).</p>
</li>
<li><p>Bn mun UI sng ng hn m khng tn cng code.</p>
</li>
<li><p>Bn ang pht trin web/app bng React hoc Flutter.</p>
</li>
</ul>
<p><strong>🚫 C th cha ph hp khi</strong></p>
<ul>
<li><p>Ch cn animation nh, tnh (CSS keyframes l ).</p>
</li>
<li><p>Cn animation cc phc tp gn cht logic app (GSAP c th hp hn).</p>
</li>
</ul>
<h2 id="heading-mot-vi-du-thuc-te">Mt v d thc t</h2>
<p>Bn c th tham kho ti <a target="_blank" href="https://rive.app/docs/runtimes/demos">https://rive.app/docs/runtimes/demos</a></p>
<h2 id="heading-rive-co-gi-dac-biet-hon-lottie">Rive c g c bit hn Lottie?</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Tnh nng</td><td><strong>Rive</strong></td><td><strong>Lottie</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Tng tc ng (State Machine)</strong></td><td> C</td><td> Khng</td></tr>
<tr>
<td><strong>Render thi gian thc (WebGL)</strong></td><td> C</td><td> Gii hn</td></tr>
<tr>
<td><strong>File nh dng</strong></td><td><code>.riv</code></td><td><code>.json</code></td></tr>
<tr>
<td><strong>D tch hp React</strong></td><td> Chnh thc h tr</td><td> C plugin</td></tr>
<tr>
<td><strong>Hiu nng &amp; kch thc file</strong></td><td>Rt nh, mt</td><td>Tt, nhng gii hn vi tng tc</td></tr>
</tbody>
</table>
</div><p>Tm li, <strong>Rive l bc tin tip theo</strong> sau Lottie  t animation th ng sang animation c tr thng minh.</p>
<h2 id="heading-hoc-rive-o-dau">Hc Rive  u?</h2>
<p>Nu bn mun bt u ngay, y l vi ti nguyn cc k hu ch:</p>
<ul>
<li><p>🌐 <a target="_blank" href="https://rive.app/">Trang ch Rive.app</a></p>
</li>
<li><p>📘 <a target="_blank" href="https://rive.app/docs/runtimes/react/react">Ti liu React SDK</a></p>
</li>
<li><p>🎓 <a target="_blank" href="https://community.rive.app/">Cng ng Rive &amp; kho animation min ph</a></p>
</li>
<li><p>🧠 <a target="_blank" href="https://www.youtube.com/@Rive_app">Video hng dn Rive c bn trn YouTube</a></p>
</li>
</ul>
<h2 id="heading-tong-ket-lai">Tng kt li</h2>
<p><strong>Rive khng ch l cng c, m l tng lai ca animation web</strong></p>
<p>Rive ang m ra mt k nguyn mi cho <strong>UI/UX animation</strong>  ni m designer v developer c th cng tc hiu qu hn, to nn nhng tri nghim tng tc mt m v thng minh hn.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/rive-la-gi</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/rive-la-gi</guid><category><![CDATA[rive]]></category><category><![CDATA[React]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[NextJS 16 chính thức ra mắt - Tính năng mới và cách sử dụng]]></title><description><![CDATA[<h2 id="heading-gioi-thieu">🌟 Gii thiu</h2>
<p>Nu bn l mt dev React, c l bn  nghe tin: <strong>NextJS 16  chnh thc ra mt</strong>.</p>
<p>Phin bn ny khng ch nng cp hiu nng m cn gii thiu hng lot cng ngh nn tng mi  t <strong>React Compiler</strong> gip ti u ha code t ng, n <strong>Partial Prerendering (PPR)</strong> cho php kt hp gia static v dynamic rendering, mang n tc  vt tri m vn gi c s linh hot.</p>
<h2 id="heading-react-compiler"> React Compiler</h2>
<p><strong>React Compiler  t ng ti u hiu sut m khng cn memo th cng</strong></p>
<p>NextJS 16 nay  <strong>h tr n nh React Compiler</strong>, mt bc tin quan trng sau khi React Compiler ra mt phin bn 1.0. y l cng c gip <strong>React t ng ti u re-render</strong>  ngha l bn khng cn phi dng <code>React.memo</code>, <code>useMemo</code>, hay <code>useCallback</code> th cng  tng hiu sut na.</p>
<p>React Compiler s phn tch m ngun component, xc nh phn no c th c memo ha an ton v thc hin t ng.</p>
<p>👉 <strong>Kt qu:</strong> hiu sut c ci thin ng k, c bit trong nhng app c nhiu component con hoc d liu phc tp.</p>
<p><strong>Cch bt React Compiler trong NextJS 16</strong></p>
<p>Thm dng cu hnh sau vo <code>next.config.ts</code>:</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// next.config.ts</span>
<span class="hljs-keyword">const</span> nextConfig = {
  reactCompiler: <span class="hljs-literal">true</span>,
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> nextConfig;
</code></pre>
<p>Ci thm plugin cn thit:</p>
<pre><code class="lang-bash">npm install babel-plugin-react-compiler@latest
</code></pre>
<p><strong>Trc khi dng React Compiler:</strong> Bn thng phi memo ha th cng  trnh render li khng cn thit.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { useMemo, useCallback, memo } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">const</span> ExpensiveComponent = memo(<span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ExpensiveComponent</span>(<span class="hljs-params">{ data, onClick }</span>) </span>{
  <span class="hljs-keyword">const</span> processedData = useMemo(<span class="hljs-function">() =&gt;</span> {
    <span class="hljs-keyword">return</span> expensiveProcessing(data);
  }, [data]);

  <span class="hljs-keyword">const</span> handleClick = useCallback(<span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> {
    onClick(item.id);
  }, [onClick]);

  <span class="hljs-keyword">return</span> (
    &lt;div&gt;
      {processedData.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> (
        &lt;Item key={item.id} onClick={<span class="hljs-function">() =&gt;</span> handleClick(item)} /&gt;
      ))}
    &lt;/div&gt;
  );
});
</code></pre>
<p> y, chng ta phi dng <code>memo</code>, <code>useMemo</code>, v <code>useCallback</code>  trnh component render li mi khi <code>data</code> hoc <code>onClick</code> thay i.</p>
<p><strong>Sau khi bt React Compiler:</strong> Ton b logic ti u ny c React t ng x l  code tr nn gn hn rt nhiu.</p>
<pre><code class="lang-typescript"><span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ExpensiveComponent</span>(<span class="hljs-params">{ data, onClick }</span>) </span>{
  <span class="hljs-keyword">const</span> processedData = expensiveProcessing(data);

  <span class="hljs-keyword">const</span> handleClick = <span class="hljs-function">(<span class="hljs-params">item</span>) =&gt;</span> {
    onClick(item.id);
  };

  <span class="hljs-keyword">return</span> (
    &lt;div&gt;
      {processedData.map(<span class="hljs-function"><span class="hljs-params">item</span> =&gt;</span> (
        &lt;Item key={item.id} onClick={<span class="hljs-function">() =&gt;</span> handleClick(item)} /&gt;
      ))}
    &lt;/div&gt;
  );
}
</code></pre>
<p>Gi bn ch cn tp trung vit logic chnh. React Compiler s lo vic <strong>ghi nh (memoize)</strong> kt qu tnh ton v trnh render tha  cho hiu sut cao m khng cn can thip th cng.</p>
<h2 id="heading-partial-prerendering-ppr-amp-cache-components"> Partial Prerendering (PPR) &amp; Cache Components</h2>
<h3 id="heading-khai-niem">Khi nim</h3>
<ul>
<li><p>Vi PPR, bn c th <strong>kt hp ni dung tnh v ng</strong> trong cng mt route: phn v ca trang c prerender (hoc cache) v gi ngay, sau  cc phn ng c load hoc streaming vo.</p>
</li>
<li><p>Tnh nng <strong>Cache Components</strong> cho php bn nh du nhng phn d liu hoc UI c th c cache  t  a chng vo prerender pass cng vi cc phn tnh ca trang.</p>
</li>
<li><p>Khi bt, NextJS s xem tt c route di dng dynamic mc nh, nhng nh Cache Components th bn vn c th chn cache cc thnh phn  y phn tnh ra sm, phn ng x l sau.</p>
</li>
</ul>
<p><img src="https://nextjs.org/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Flearn%2Fdark%2Fthinking-in-ppr.png&amp;w=3840&amp;q=75" alt="Partially re-rendered Product Page showing static nav and product information, and dynamic cart and recommended products" /></p>
<h3 id="heading-cach-hoat-dong-amp-loi-ich">Cch hot ng &amp; li ch</h3>
<ul>
<li><p>Khi ngi dng truy cp mt route: server tr nhanh phn shell (v) c ni dung c cache/prerender; cc phn ng  thng c t trong <code>Suspense</code> hoc tng t  tr fallback trc ri b thay th khi d liu/dynamic component sn sng.</p>
</li>
<li><p>Kt qu l: thi gian ti <strong>first byte (TTFB)</strong> ngn hn; ngi dng nhn thy nhanh; phn ng vn c th c nhn ha hoc cp nht real-time khi cn.</p>
</li>
<li><p>V d in hnh: trang sn phm c nav + thng tin sn phm (tnh) v gi hng +  xut sn phm (ng). Phn tnh c prerender, phn ng s streaming.</p>
</li>
</ul>
<h3 id="heading-cach-su-dung-co-ban">Cch s dng c bn</h3>
<ul>
<li><p>Trong file route/layout/component bn c th s dng directive <code>'use cache'</code>  u file hoc component  bt caching cho phn .</p>
<pre><code class="lang-typescript">  <span class="hljs-comment">// example.tsx</span>
  <span class="hljs-string">'use cache'</span>;
  <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">CachedSection</span>(<span class="hljs-params"></span>) </span>{
    <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> fetch(...); <span class="hljs-comment">// d liu c th cache</span>
    <span class="hljs-keyword">return</span> &lt;div&gt;{data.someField}&lt;/div&gt;;
  }
</code></pre>
</li>
<li><p>Cu hnh trong <code>next.config.js</code> nu cn bt cc tnh nng th nghim nh PPR hoc use-cache:</p>
<pre><code class="lang-javascript">  <span class="hljs-comment">// next.config.js</span>
  <span class="hljs-built_in">module</span>.exports = {
    <span class="hljs-attr">experimental</span>: {
      <span class="hljs-attr">ppr</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">useCache</span>: <span class="hljs-literal">true</span>,
    },
  };
</code></pre>
</li>
<li><p>S dng cc API <code>fetch</code> vi options nh <code>next: { revalidate:  }</code>  kim sot cp nht cache.</p>
</li>
</ul>
<h3 id="heading-nhung-luu-y">Nhng lu </h3>
<ul>
<li><p>PPR hin vn c gn mc <strong>experimental</strong> (tu phin bn) nn cha khuyn khch s dng rng ri trong production.</p>
</li>
<li><p>Khi dng caching: cn cn nhc <strong>tnh ti mi (fresh data) ca d liu</strong>, v cache lu qu c th dn ti hin th d liu li thi. Revalidation (nh thi hoc theo tag) lun l phn quan trng.</p>
</li>
<li><p>Khi dng directive <code>'use cache'</code>, cc hm/tr v ca chng <strong>phi c tnh tham chiu r rng</strong> (cc tham s serializable)  key cache c xc nh ng.</p>
</li>
</ul>
<p><strong>V d:</strong> Gi s bn c trang sn phm kiu e-commerce</p>
<pre><code class="lang-typescript"><span class="hljs-comment">// app/product/[id]/page.tsx</span>
<span class="hljs-keyword">import</span> { Suspense } <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">ProductPage</span>(<span class="hljs-params">{ params }</span>) </span>{
  <span class="hljs-keyword">const</span> { id } = params;

  <span class="hljs-comment">// Thnh phn tnh / c th cache</span>
  <span class="hljs-keyword">const</span> product = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`/api/product/<span class="hljs-subst">${id}</span>`</span>, { next: { revalidate: <span class="hljs-number">3600</span> } });

  <span class="hljs-keyword">return</span> (
    &lt;div&gt;
      &lt;h1&gt;{product.name}&lt;/h1&gt;
      &lt;p&gt;{product.description}&lt;/p&gt;

      {<span class="hljs-comment">/* Thnh phn ng: gi hng, neri sn phm */</span>}
      &lt;Suspense fallback={&lt;div&gt;Loading cart &amp; recommendations&lt;/div&gt;}&gt;
        &lt;Cart userId={<span class="hljs-comment">/* t cookie */</span>} /&gt;
        &lt;Recommendations productId={id} /&gt;
      &lt;/Suspense&gt;
    &lt;/div&gt;
  );
}
</code></pre>
<p><strong> y:</strong> phn <code>name</code>/<code>description</code> c cache/prerender; phn <code>Cart</code> v <code>Recommendations</code> c render ng sau, nh  ngi dng nhanh nhn thy ni dung chnh, phn ph ti sau.</p>
<h2 id="heading-nextjs-devtools-mcp">🧠 NextJS DevTools MCP</h2>
<p>Mt im mi th v trong <strong>NextJS 16</strong> l <strong>NextJS DevTools MCP</strong>  tch hp theo chun <strong>Model Context Protocol (MCP)</strong>, gip AI c th <strong>hiu r ng cnh ng dng ca bn khi debug</strong>.</p>
<p>Thay v phi t ln m qua log hay stack trace, DevTools MCP cho php <strong>AI agent</strong> (nh ChatGPT hoc cng c tng t) truy cp trc tip vo thng tin ni b ca ng dng ang chy  phn tch v h tr gi  fix li thng minh hn.</p>
<p>🔍 <strong>AI DevTools hiu c nhng g?</strong></p>
<ul>
<li><p><strong>Kin thc v NextJS:</strong> nm r cch routing, caching v rendering hot ng.</p>
</li>
<li><p><strong>Log hp nht:</strong> t ng thu thp c log t trnh duyt v server  khng cn chuyn tab.</p>
</li>
<li><p><strong>Truy cp li t ng:</strong> ly chi tit stack trace v error context m bn khng cn copy th cng.</p>
</li>
<li><p><strong>Hiu ng cnh trang:</strong> bit bn ang  route no, gip phn hi chnh xc v lin quan hn.</p>
</li>
</ul>
<p>Bn c th xem thm chi tit trong ti liu ti <a target="_blank" href="https://nextjs.org/docs/app/guides/mcp">NextJS DevTools MCP docs.</a></p>
<h2 id="heading-proxyts">🔀 proxy.ts</h2>
<p><code>proxy.ts</code> thay th cho <code>middleware.ts</code>, r rng v thng nht hn</p>
<p>Trong <strong>NextJS 16</strong>, file <code>proxy.ts</code> chnh thc <strong>thay th cho</strong> <code>middleware.ts</code>  nhm lm r ranh gii mng (network boundary) ca ng dng v m bo tnh nht qun khi x l request.</p>
<p>Trc y, <code>middleware.ts</code> c th chy trn nhiu runtime khc nhau (Edge hoc Node.js), dn n kh d on hnh vi v mi trng chy. Gi y, <code>proxy.ts</code> lun chy trn Node.js runtime, gip developer d hiu v debug hn.</p>
<h4 id="heading-can-lam-gi-khi-nang-cap">💡 Cn lm g khi nng cp</h4>
<ul>
<li><p>i tn file:</p>
<pre><code class="lang-typescript">  middleware.ts  proxy.ts
</code></pre>
</li>
<li><p>i tn hm export:</p>
<pre><code class="lang-typescript">  <span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">proxy</span>(<span class="hljs-params">request: NextRequest</span>) </span>{
    <span class="hljs-keyword">return</span> NextResponse.redirect(<span class="hljs-keyword">new</span> URL(<span class="hljs-string">'/home'</span>, request.url));
  }
</code></pre>
</li>
<li><p>Logic x l trong file <strong>gi nguyn</strong>, ch cn i tn cho ph hp.</p>
</li>
</ul>
<h4 id="heading-ly-do-thay-doi"> L do thay i</h4>
<ul>
<li><p><strong>Tn proxy r ngha hn:</strong> phn nh ng vai tr chn, chuyn hng, hoc x l request trc khi ti route chnh.</p>
</li>
<li><p><strong>Runtime thng nht:</strong> ch chy trn <strong>Node.js</strong>, gip trnh nhm ln gia mi trng Edge v server truyn thng.</p>
</li>
</ul>
<blockquote>
<p>🧭 <strong>Lu :</strong></p>
<ul>
<li><p><code>middleware.ts</code> vn tm thi c h tr cho <strong>Edge runtime</strong>, nhng  <strong>deprecated</strong> v s b loi b trong phin bn tng lai.</p>
</li>
<li><p>Hy sm chuyn sang <code>proxy.ts</code>  m bo tng thch lu di.</p>
</li>
</ul>
</blockquote>
<p>Xem thm hng dn chi tit <a target="_blank" href="https://nextjs.org/docs/app/getting-started/proxy">ti y</a></p>
<h2 id="heading-fast-refresh-moi">🔁 Fast Refresh mi</h2>
<p>Ai code React cng bit cm gic ny: sa file  lu  i reload vi trm mili giy n vi giy.<br />Gi th khng cn na.</p>
<p>Vi <strong>Fast Refresh mi</strong> trong NextJS 16, nh <strong>React Compiler</strong> v <strong>Turbopack</strong>, mi khi bn lu file:</p>
<ul>
<li><p>Code c bin dch li gn nh ngay lp tc.</p>
</li>
<li><p>Trng thi component c gi nguyn.</p>
</li>
</ul>
<p><strong>V d:</strong> bn ang dev form hoc counter  thay i UI, nhn save  trnh duyt cp nht <strong>ngay tc th</strong> m khng reset d liu.</p>
<h2 id="heading-turbopack-updates"> Turbopack Updates</h2>
<p>NextJS 16 tip tc ci thin <strong>Turbopack</strong>, trnh build th h mi thay th Webpack.<br />Hiu nng build gi <strong>nhanh hn ti 40%</strong>, c bit vi project ln hoc monorepo.</p>
<p>Bn c th cm nhn ngay khi chy:</p>
<pre><code class="lang-bash">npx create-next-app@latest my-app
</code></pre>
<p>Turbopack l build engine mc nh, khng cn ci thm g c.<br />V nu bn tng chu kh vi Webpack build lu, bn s thch Turbopack ngay t ln u chy.</p>
<h2 id="heading-react-19-support"> React 19 Support</h2>
<p>NextJS 16 c xy dng  hot ng mt m cng <strong>React 19</strong>.<br />iu ny gip tn dng y  cc tnh nng mi:</p>
<ul>
<li><p><strong>Actions &amp; Form Handling:</strong> gi form v thc thi logic m khng cn fetch th cng.</p>
</li>
<li><p><strong>Async Context:</strong> chia s d liu bt ng b d dng.</p>
</li>
<li><p><strong>Ci tin Hooks:</strong> gip code React d qun l hn.</p>
</li>
</ul>
<h2 id="heading-dx-amp-build-improvements">💻 DX &amp; Build Improvements</h2>
<p>Vercel tip tc u t mnh vo <strong>DX (Developer Experience)</strong>:</p>
<ul>
<li><p><img src="https://nextjs.org/_next/image?url=https%3A%2F%2Fh8DxKfmAPhn8O0p3.public.blob.vercel-storage.com%2Fstatic%2Fblog%2Fnext-16%2Fdevelopment-log.jpg&amp;w=1920&amp;q=75" alt /></p>
<p>  Thng bo li r rng, d hiu.</p>
</li>
<li><p>Log build chi tit hn.</p>
</li>
<li><p>Gi  fix khi cu hnh sai.</p>
</li>
<li><p>Tch hp tt hn vi VS Code v TypeScript.</p>
</li>
</ul>
<pre><code class="lang-typescript"> Next.js <span class="hljs-number">16</span> (Turbopack)

  Compiled successfully <span class="hljs-keyword">in</span> <span class="hljs-number">615</span>ms
  Finished TypeScript <span class="hljs-keyword">in</span> <span class="hljs-number">1114</span>ms
  Collecting page data <span class="hljs-keyword">in</span> <span class="hljs-number">208</span>ms
  Generating <span class="hljs-keyword">static</span> pages <span class="hljs-keyword">in</span> <span class="hljs-number">239</span>ms
  Finalizing page optimization <span class="hljs-keyword">in</span> <span class="hljs-number">5</span>ms
</code></pre>
<h2 id="heading-improved-caching-apis">🧾 Improved Caching APIs</h2>
<p>Trong <strong>NextJS 16</strong>, h thng cache c tinh chnh mnh m hn vi <strong>cc API mi v ci tin</strong>, gip dev kim sot r rng cch d liu c lu, lm mi v cp nht trong ng dng.</p>
<p>Ba API ni bt trong ln cp nht ny gm: <code>revalidateTag()</code> (c nng cp), <code>updateTag()</code> (mi), v <code>refresh()</code> (mi).</p>
<p><strong></strong> <code>revalidateTag()</code> <strong> h tr stale-while-revalidate (SWR)</strong></p>
<p>API ny c cp nht  bn c th ch nh <strong>profile cacheLife</strong>  gip d liu c vn c tr v ngay lp tc trong khi NextJS <strong>ngm revalidate</strong>  background.</p>
<pre><code class="lang-typescript"><span class="hljs-keyword">import</span> { revalidateTag } <span class="hljs-keyword">from</span> <span class="hljs-string">'next/cache'</span>;

<span class="hljs-comment">//  Dng profile c sn (gi  dng 'max' cho hu ht trng hp)</span>
revalidateTag(<span class="hljs-string">'blog-posts'</span>, <span class="hljs-string">'max'</span>);

<span class="hljs-comment">// Hoc chn profile khc</span>
revalidateTag(<span class="hljs-string">'news-feed'</span>, <span class="hljs-string">'hours'</span>);
revalidateTag(<span class="hljs-string">'analytics'</span>, <span class="hljs-string">'days'</span>);

<span class="hljs-comment">// Ty chnh thi gian revalidate th cng</span>
revalidateTag(<span class="hljs-string">'products'</span>, { revalidate: <span class="hljs-number">3600</span> });

<span class="hljs-comment">//  Deprecated: dng c ch truyn 1 tham s</span>
revalidateTag(<span class="hljs-string">'blog-posts'</span>);
</code></pre>
<p>Cc profile (<code>'max'</code>, <code>'hours'</code>, <code>'days'</code>) c th c nh ngha sn trong <code>next.config</code>.<br />Khi ngi dng request d liu c tag tng ng, <strong>NextJS tr cache ngay</strong> v <strong>lm mi  background</strong>, gi tri nghim nhanh m vn m bo d liu khng qu c.</p>
<p>👉 Dng <code>revalidateTag()</code> cho cc ni dung tnh (v d: blog, news feed, sn phm)  ni bn <strong>chp nhn  tr nh khi cp nht</strong>  i ly tc  ti nhanh.</p>
<blockquote>
<p><strong>Hng dn nng cp:</strong><br />Nu bn ang dng <code>revalidateTag('tagName')</code>, hy thm tham s th hai (v d <code>'max'</code>)  bt SWR behavior.<br />Nu bn cn hnh vi c ngay sau khi ghi (read-your-writes), hy dng <code>updateTag()</code> thay th.</p>
</blockquote>
<p> <code>updateTag()</code>  cp nht cache ngay lp tc</p>
<p>y l API mi, dng trong <strong>Server Actions</strong>, gip <strong>invalidate cache v c li d liu mi ngay trong cng request</strong>.</p>
<p>Rt hu ch cho cc hnh ng tng tc (form, ci t, cp nht h s, v.v.), ni ngi dng cn thy kt qu thay i <strong>ngay lp tc</strong>.</p>
<pre><code class="lang-typescript"><span class="hljs-string">'use server'</span>;

<span class="hljs-keyword">import</span> { updateTag } <span class="hljs-keyword">from</span> <span class="hljs-string">'next/cache'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">updateUserProfile</span>(<span class="hljs-params">userId: <span class="hljs-built_in">string</span>, profile: Profile</span>) </span>{
  <span class="hljs-keyword">await</span> db.users.update(userId, profile);

  <span class="hljs-comment">// Ht hn cache v c li d liu mi ngay</span>
  updateTag(<span class="hljs-string">`user-<span class="hljs-subst">${userId}</span>`</span>);
}
</code></pre>
<blockquote>
<p>💡 Dng <code>updateTag()</code> khi cn d liu c cp nht <strong>trc quan v tc thi</strong>, m bo ngi dng thy kt qu mi ngay sau thao tc.</p>
</blockquote>
<p>🔄 <code>refresh()</code>  lm mi d liu khng cache</p>
<p>Cng dnh cho <strong>Server Actions</strong>, <code>refresh()</code> gip cp nht li <strong>cc phn d liu ng khng c cache</strong>  m khng nh hng n phn tnh ca trang.</p>
<pre><code class="lang-typescript"><span class="hljs-string">'use server'</span>;

<span class="hljs-keyword">import</span> { refresh } <span class="hljs-keyword">from</span> <span class="hljs-string">'next/cache'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">markNotificationAsRead</span>(<span class="hljs-params">notificationId: <span class="hljs-built_in">string</span></span>) </span>{
  <span class="hljs-keyword">await</span> db.notifications.markAsRead(notificationId);

  <span class="hljs-comment">// Lm mi phn hin th s thng bo (khng cache)</span>
  refresh();
}
</code></pre>
<p><strong>Dng trong cc trng hp nh:</strong></p>
<ul>
<li><p>Lm mi s lng thng bo cha c.</p>
</li>
<li><p>Cp nht trng thi online / live metrics.</p>
</li>
<li><p>Refresh d liu ng m khng cn re-render ton b trang.</p>
</li>
</ul>
<div class="hn-table">
<table>
<thead>
<tr>
<td>API</td><td>Dng cho</td><td>Hnh vi chnh</td></tr>
</thead>
<tbody>
<tr>
<td><code>revalidateTag()</code></td><td>Ni dung tnh, cache lu</td><td>Tr cache ngay, revalidate nn</td></tr>
<tr>
<td><code>updateTag()</code></td><td>Tc v ngi dng</td><td>Lm mi cache &amp; c li tc th</td></tr>
<tr>
<td><code>refresh()</code></td><td>D liu khng cache</td><td>Refresh phn ng m khng ng ti cache</td></tr>
</tbody>
</table>
</div><h2 id="heading-tai-lieu-tham-khao">Ti liu tham kho</h2>
<ul>
<li><a target="_blank" href="https://nextjs.org/blog/next-16">Next.js 16</a></li>
</ul>
]]></description><link>https://blog.thanhnamnguyen.dev/nextjs-16-chinh-thuc-ra-mat</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/nextjs-16-chinh-thuc-ra-mat</guid><category><![CDATA[Next.js]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Coolify là gì? Hướng dẫn triển khai ứng dụng tự host siêu đơn giản với Coolify]]></title><description><![CDATA[<h2 id="heading-coolify-tu-host-app-chuyen-nghiep-ma-de-nhu-choi-game">Coolify  T host app chuyn nghip m d nh chi game!</h2>
<p>Trong thi i mi th u as a Service, vic t trin khai ng dng thng b xem l phc tp, tn thi gian, i hi phi rnh DevOps hoc t nht l bit cch cu hnh server. Nhng ch ! Gi y bn c th t tay trin khai mt ng dng full-stack ch trong vi pht, m chng cn phi chm n dng lnh rc ri no  nh <strong>Coolify</strong>.</p>
<p>Trong bi vit ny, chng ta s cng nhau khm ph:</p>
<ul>
<li><p> Coolify l g v n gip ch g cho developer?</p>
</li>
<li><p> Cch ci t Coolify ch vi mt dng lnh.</p>
</li>
<li><p> Cch kt ni Git, trin khai app, v cu hnh mi trng.</p>
</li>
<li><p> Nhng ng dng bn c th trin khai bng Coolify (Laravel, Next.js, Node.js, v.v.)</p>
</li>
<li><p> Tips v li khuyn  ti u tri nghim Coolify.</p>
</li>
</ul>
<h2 id="heading-coolify-la-gi">Coolify l g?</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748168055378/358e52b1-5bf4-42df-9dfc-bab6cffaf3d3.png" alt="Coolify l g?" class="image--center mx-auto" /></p>
<p><strong>Coolify</strong> l mt nn tng <em>self-hosted PaaS (Platform as a Service)</em>  ngha l bn t chy n trn server ca mnh, nhng li c giao din qun l cc k d dng, ging nh tri nghim trn Vercel, Heroku, hay Netlify.</p>
<p><strong>Vi Coolify bn c th:</strong></p>
<ul>
<li><p>T deploy app backend/frontend mt cch t ng, d dng.</p>
</li>
<li><p>Kt ni thng n GitHub/GitLab.</p>
</li>
<li><p>Qun l mi trng (ENV), build images bng Docker.</p>
</li>
<li><p>Theo di logs, trng thi app, restart app d dng.</p>
</li>
<li><p>M rng server nu cn (h tr Docker Swarm &amp; Traefik).</p>
</li>
</ul>
<p>📌 <strong>iu c bit:</strong> bn c ton quyn qun l, khng b gii hn ti nguyn hay chnh sch nh cc nn tng m my min ph.</p>
<h2 id="heading-tai-sao-nen-dung-coolify">Ti sao nn dng Coolify?</h2>
<ul>
<li><p>🧑💻 <strong>Thn thin vi developer:</strong> C UI trc quan, khng cn bit nhiu v h tng.</p>
</li>
<li><p>💸 <strong>Tit kim chi ph:</strong> Ch cn 1 VPS gi r (~5-10$/thng), bn c th deploy nhiu app.</p>
</li>
<li><p>🛠 <strong>T do tuyt i:</strong> T host = khng b gii hn, ton quyn qun l app ca mnh.</p>
</li>
<li><p>🔒 <strong>Bo mt hn:</strong> Bn kim sot d liu v h thng ca mnh 100%.</p>
</li>
</ul>
<h2 id="heading-cai-dat-coolify-nhanh-gon-trong-mot-dong-lenh">Ci t Coolify  nhanh gn trong mt dng lnh</h2>
<p>Coolify c xy dng  d ci t nht c th. Tt c nhng g bn cn l mt my ch c <strong>Docker</strong>  ci t sn (Ubuntu VPS l gi  ph bin).</p>
<p><strong>Cu hnh VPS ti thiu:</strong></p>
<ul>
<li><p><strong>CPU</strong>: 2 cores</p>
</li>
<li><p><strong>Memory (RAM)</strong>: 2 GB</p>
</li>
<li><p><strong>Storage</strong>: 30 GB of free space</p>
</li>
</ul>
<h3 id="heading-buoc-1-ssh-vao-server">Bc 1: SSH vo server</h3>
<pre><code class="lang-bash">ssh root@your-vps-ip
</code></pre>
<h3 id="heading-buoc-2-cai-docker-neu-chua-co">Bc 2: Ci Docker (nu cha c)</h3>
<pre><code class="lang-bash">curl -fsSL https://get.docker.com -o get-docker.sh &amp;&amp; sh get-docker.sh
</code></pre>
<h3 id="heading-buoc-3-cai-dat-coolify">Bc 3: Ci t Coolify</h3>
<pre><code class="lang-bash">curl -fsSL https://cdn.coollabs.io/coolify/install.sh | bash
</code></pre>
<p>💡 Sau khi ci t, bn c th truy cp giao din web qua <code>http://your-server-ip</code>  cu hnh ln u. Nu khng vo c, hy thit lp tng la trn VPS vi cc cng 80 v 443 (giao thc TCP).</p>
<h2 id="heading-tao-tai-khoan-quan-tri-dau-tien">To ti khon qun tr u tin</h2>
<p>Sau khi truy cp trnh duyt, bn s thy giao din ng k ti khon qun tr Coolify. in email v mt khu, sn sng  deploy ng dng!</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748165556535/957a00bd-3f99-4869-afe1-5c6482b120bc.png" alt="To ti khon qun tr u tin" class="image--center mx-auto" /></p>
<h2 id="heading-cach-deploy-ung-dung-voi-coolify">Cch deploy ng dng vi Coolify</h2>
<h3 id="heading-buoc-1-ket-noi-git-tao-github-app">Bc 1: Kt ni Git, to Github App</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748165676241/2aabd797-51bb-44d1-b920-09e1ae348110.png" alt="Bc 1: Kt ni Git" class="image--center mx-auto" /></p>
<p>Coolify h tr kt ni vi:</p>
<ul>
<li><p>GitHub</p>
</li>
<li><p>GitLab</p>
</li>
<li><p>Gitea (self-hosted)</p>
</li>
</ul>
<p>Sau khi kt ni, bn ch cn chn repo mun deploy.</p>
<h3 id="heading-buoc-2-cau-hinh-moi-truong">Bc 2: Cu hnh mi trng</h3>
<p>Chn:</p>
<ul>
<li><p>Loi ng dng: Static / Node.js / Laravel / Docker Image</p>
</li>
<li><p>Cu hnh ENV (API_KEY, DATABASE_URL)</p>
</li>
<li><p>Ch nh Dockerfile nu c</p>
</li>
</ul>
<h3 id="heading-buoc-3-trien-khai-ung-dung">Bc 3: Trin khai ng dng</h3>
<p>Nhn nt <strong>Deploy</strong>  v i vi pht  Coolify build + start app cho bn.</p>
<p>🧪 Coolify s t ng detect framework ph bin nh Next.js, Nuxt.js, Laravel, React, v.v.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748166018509/2e43b2f3-29cd-4bd1-8a47-1422b033162a.png" alt="Trin khai ng dng" class="image--center mx-auto" /></p>
<h2 id="heading-he-thong-giam-sat-va-logs">H thng gim st v logs</h2>
<p>Coolify cho php bn:</p>
<ul>
<li><p>Theo di trng thi ng dng theo thi gian thc</p>
</li>
<li><p>Restart / dng app d dng</p>
</li>
<li><p>Xem logs h thng ngay trong dashboard</p>
</li>
</ul>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1748166218328/cefd4ad9-1348-4dda-ae61-dfb118544956.png" alt="H thng gim st v logs" class="image--center mx-auto" /></p>
<h2 id="heading-quan-ly-domain-va-https-voi-traefik">Qun l domain v HTTPS vi Traefik</h2>
<p>Coolify tch hp sn <strong>Traefik</strong>  h thng reverse proxy mnh m:</p>
<ul>
<li><p>T ng cp HTTPS vi Lets Encrypt</p>
</li>
<li><p>Qun l routing cc app qua subdomain</p>
</li>
<li><p>Khng cn config NGINX th cng 🎉</p>
</li>
</ul>
<h2 id="heading-mot-so-meo-huu-ich-khi-dung-coolify">Mt s mo hu ch khi dng Coolify</h2>
<ul>
<li><p>Dng VPS t nht 2 vCPU + 2GB RAM  trnh nghn ti nguyn khi chy nhiu app.</p>
</li>
<li><p>Backup thng xuyn bng chc nng sao lu built-in ca Coolify.</p>
</li>
<li><p>S dng <code>Coolify CLI</code>  qun l nng cao nu cn.</p>
</li>
<li><p>Trin khai cng Docker Swarm nu mun m rng h thng.</p>
</li>
</ul>
<h2 id="heading-so-sanh-coolify-voi-cac-nen-tang-khac">So snh Coolify vi cc nn tng khc</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Tnh nng</td><td>Coolify</td><td>Vercel</td><td>Heroku</td></tr>
</thead>
<tbody>
<tr>
<td>T host</td><td></td><td></td><td></td></tr>
<tr>
<td>UI p, d dng</td><td></td><td></td><td></td></tr>
<tr>
<td>Tch hp Git</td><td></td><td></td><td></td></tr>
<tr>
<td>Min ph</td><td></td><td>C gii hn</td><td>C gii hn</td></tr>
<tr>
<td>H tr Docker</td><td></td><td></td><td></td></tr>
</tbody>
</table>
</div><h2 id="heading-cac-ung-dung-phu-hop-voi-coolify">Cc ng dng ph hp vi Coolify</h2>
<ul>
<li><p>Laravel</p>
</li>
<li><p>Node.js / Express</p>
</li>
<li><p>Next.js / Nuxt.js</p>
</li>
<li><p>React / Vue (static build)</p>
</li>
<li><p>WordPress (qua Docker image)</p>
</li>
<li><p>PostgreSQL, MySQL, Redis, v.v.</p>
</li>
</ul>
<h2 id="heading-mot-so-video-huong-dan-co-ban">Mt s video hng dn c bn</h2>
<p>Tham kho ti <a target="_blank" href="https://coolify.io/docs/get-started/videos">https://coolify.io/docs/get-started/videos</a></p>
<p>Nu bn tng ngi deploy v s rc ri hoc thiu kinh nghim DevOps, th Coolify chnh l la chn tt dnh cho bn. Vi mt giao din cc k thn thin, kh nng tch hp Git, h tr Docker mnh m  Coolify gip bn <em>lm ch h tng</em> ch vi vi c nhp chut.</p>
<h3 id="heading-tham-khao-them">Tham kho thm</h3>
<ul>
<li><p><a target="_blank" href="https://coolify.io/">Trang chnh thc Coolify</a></p>
</li>
<li><p><a target="_blank" href="https://coolify.io/docs/get-started/introduction">Ti liu chi tit</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/coollabsio/coolify">Coolify trn GitHub</a></p>
</li>
</ul>
]]></description><link>https://blog.thanhnamnguyen.dev/huong-dan-su-dung-coolify-tu-host-app</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/huong-dan-su-dung-coolify-tu-host-app</guid><category><![CDATA[coolify]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Cursify – Cursor Aninmation mã nguồn mở dành cho React và NextJS]]></title><description><![CDATA[<p>Chuyn l mnh ang tm 1 th vin hay m ngun m  custom con tr chut (cursor) cho website c nhn ca mnh. Tnh c tm c 1 m ngun m l Cursify  custom cursor, sau 1 thi gian ngn tri nghim, mnh thy kh ng nn vit bi ny  chia s cho mi ngi nu c nhu cu s dng.</p>
<h2 id="heading-cursify-la-gi">🚀 Cursify l g?</h2>
<p><a target="_blank" href="https://cursify.vercel.app/">Cursify</a> l mt repo m ngun m c xy dng bi React, TypeScrips, Tailwind, Framer motion gip bn to ra <strong>hiu ng con tr chut hot nh ty chnh</strong> mt cch n gin, nh nhng nhng cc k bt mt. Vi m ngun m, th vin ny khng ch min ph m cn d dng tch hp v chnh sa theo nhu cu ring ca bn.</p>
<blockquote>
<p>👉 Bn c th tri nghim trc tip ti y: <a target="_blank" href="https://cursify.vercel.app/components">Cursify</a></p>
</blockquote>
<h2 id="heading-cong-nghe-duoc-su-dung">🛠 Cng ngh c s dng</h2>
<p>Cursify khng ch p m cn c xy dng trn nn tng nhng cng ngh hin i trong lp trnh frontend:</p>
<ul>
<li><p><strong>React</strong>  Framework ph bin  xy dng giao din ng.</p>
</li>
<li><p><strong>TypeScript</strong>  Ngn ng mnh m gip tng tnh n nh v d bo tr.</p>
</li>
<li><p><strong>Tailwind CSS</strong>  Framework CSS utility-first gip style ha nhanh chng.</p>
</li>
<li><p><strong>Framer Motion</strong>  Th vin hot nh mt m, cc d tch hp vo React.</p>
</li>
</ul>
<p>S kt hp ny gip Cursify khng ch gn nh m cn cc k linh hot, d dng v d custom.</p>
<h2 id="heading-nhung-tinh-nang-noi-bat-cua-cursify"> Nhng tnh nng ni bt ca Cursify</h2>
<ul>
<li><p>🔁 <strong>Hot nh mt m</strong>: Hiu ng chuyn ng mm mi nh Framer Motion.</p>
</li>
<li><p>🎨 <strong>Ty chnh linh hot</strong>: D dng thay i mu sc, hnh dng v hiu ng.</p>
</li>
<li><p>🧠 <strong>Vit bng TypeScript</strong>: Gip gim li v ci thin tri nghim lp trnh.</p>
</li>
<li><p>💡 <strong>Thit k ti gin</strong>: Ph hp vi hu ht phong cch UI hin i.</p>
</li>
<li><p> <strong>Hiu sut cao</strong>: Khng lm chm website ca bn (ci ny th tu nha, my trnh duyt khc mnh thy nhanh, tuy nhin s dng Google Chrome li kh git t 1 s custom cursor).</p>
</li>
</ul>
<h2 id="heading-cach-cai-dat-va-su-dung">📦 Cch ci t v s dng</h2>
<p>Bn c th thm Cursify vo d n React ca mnh ch vi vi bc n gin:</p>
<h3 id="heading-buoc-1-cai-dat-thu-vien-framer-motion-va-tailwind">Bc 1: Ci t th vin framer-motion v tailwind</h3>
<p>Mt s custom cursor cn s dng th vin framer-motion th nn mnh cn ci n.</p>
<pre><code class="lang-bash">npm install framer-motion clsx tailwind-merge
</code></pre>
<p>Hoc nu bn dng Yarn:</p>
<pre><code class="lang-bash">yarn add framer-motion clsx tailwind-merge
</code></pre>
<p>Tng t cho pnpm v bun.</p>
<h3 id="heading-buoc-2-tao-file-utilsts">Bc 2: To file utils.ts</h3>
<pre><code class="lang-typescript"><span class="hljs-comment">// lib/utils.ts</span>
<span class="hljs-keyword">import</span> { <span class="hljs-keyword">type</span> ClassValue, clsx } <span class="hljs-keyword">from</span> <span class="hljs-string">'clsx'</span>;
<span class="hljs-keyword">import</span> { twMerge } <span class="hljs-keyword">from</span> <span class="hljs-string">'tailwind-merge'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cn</span>(<span class="hljs-params">...inputs: ClassValue[]</span>) </span>{
  <span class="hljs-keyword">return</span> twMerge(clsx(inputs));
}
</code></pre>
<h3 id="heading-buoc-3-custom-cursor">Bc 3: Custom cursor</h3>
<p>Truy cp <a target="_blank" href="https://cursify.vercel.app/components">Cursify</a>  copy custom cursor mnh cn, to hook v import l c th s dng.</p>
<h2 id="heading-demo">📹 Demo</h2>
<div class="embed-wrapper"><div class="embed-loading"><div class="loadingRow"></div><div class="loadingRow"></div></div><a class="embed-card" href="https://www.youtube.com/watch?v=XpfGdAz5suw">https://www.youtube.com/watch?v=XpfGdAz5suw</a></div>
<p> </p>
<h2 id="heading-mot-so-vi-du-su-dung-cursify">📸 Mt s v d s dng Cursify</h2>
<ul>
<li><p>Portfolio c nhn</p>
</li>
<li><p>Website agency sng to</p>
</li>
<li><p>Landing page sn phm</p>
</li>
<li><p>Blog c nhn hin i</p>
</li>
</ul>
<h2 id="heading-tai-nguyen-huu-ich">🔗 Ti nguyn hu ch</h2>
<ul>
<li><p>🌐 <a target="_blank" href="https://cursify.vercel.app/">Trang chnh thc (demo)</a></p>
</li>
<li><p>💻 <a target="_blank" href="https://github.com/ui-layouts/cursify">GitHub Repository</a></p>
</li>
<li><p>🧠 Tm hiu thm v <a target="_blank" href="https://motion.dev/">Framer Motion</a></p>
</li>
</ul>
<h2 id="heading-ket-lai">🎯 Kt li</h2>
<p>Nu bn ang mun to mt tri nghim ngi dng hin i, bt mt m khng mun mt qu nhiu cng sc, th <strong>Cursify</strong> chnh l cng c bn nn th ngay. D ci, d dng, li cn p  ng kiu chn i cho lp trnh vin front-end.</p>
<p>Hy th tch hp Cursify vo d n tip theo ca bn v cm nhn s khc bit nha! 😎</p>
]]></description><link>https://blog.thanhnamnguyen.dev/cursify-cursor-aninmation</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/cursify-cursor-aninmation</guid><category><![CDATA[animation]]></category><category><![CDATA[React]]></category><category><![CDATA[Next.js]]></category><category><![CDATA[cursor]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[CSS Sprite, Image Sprite: Cách tối ưu hóa hình ảnh hiệu quả cho Website]]></title><description><![CDATA[<p>CSS Sprite l mt mo gip ti u ha hnh nh bng cch gp nhiu nh nh thnh mt nh duy nht, gip gim s lng yu cu HTTP v ci thin hiu sut ti trang. Bi vit ny s hng dn bn cch s dng CSS Sprite  ti u website hiu qu.</p>
<h3 id="heading-1-css-sprite-va-image-sprite-la-gi"><strong>1. CSS Sprite v Image Sprite l g?</strong></h3>
<p>CSS Sprite (hay Image Sprite) l k thut ti u ha hnh nh bng cch gp nhiu hnh nh nh thnh mt tp hnh nh duy nht, sau  s dng CSS  hin th tng phn hnh nh theo v tr mong mun.</p>
<p>K thut ny gip gim s lng request HTTP khi ti trang, tng tc  load website, v ti u hiu sut tng th.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1741540907956/fb64e69d-185f-4504-9450-d5a9543491e9.gif" alt="CSS Sprite v Image Sprite l g" class="image--center mx-auto" /></p>
<p><strong>V d:</strong> Nu mt trang web c 10 icon nh, thay v ti tng icon mt (10 request HTTP), bn c th gp chng vo mt nh duy nht v ch cn 1 request.</p>
<h3 id="heading-2-loi-ich-cua-css-sprite"><strong>2. Li ch ca CSS Sprite</strong></h3>
<ul>
<li><p><strong>Gim s lng HTTP Requests:</strong> Gip trnh duyt ti trang nhanh hn bng cch gim s lng file hnh nh cn ti.</p>
</li>
<li><p><strong>Ci thin hiu sut trang web:</strong> t request hn ng ngha vi vic ti nhanh hn, c bit quan trng vi cc website c nhiu hnh nh nh nh menu, icon, button,...</p>
</li>
<li><p><strong>Tit kim bng thng:</strong> V tt c hnh nh gp chung vo mt file, tng dung lng ti xung c th nh hn so vi ti tng nh ring l.</p>
</li>
<li><p><strong>Gip website thn thin vi SEO:</strong> Google nh gi cao tc  ti trang, t  ci thin th hng trn cng c tm kim.</p>
</li>
</ul>
<h3 id="heading-3-cach-tao-va-su-dung-css-sprite"><strong>3. Cch to v s dng CSS Sprite</strong></h3>
<h4 id="heading-buoc-1-gop-nhieu-hinh-anh-thanh-mot-file-duy-nhat"><strong>Bc 1: Gp nhiu hnh nh thnh mt file duy nht</strong></h4>
<p>Bn c th t to mt file sprite bng cch s dng phn mm Photoshop, Figma, hoc cc cng c online nh:<br />👉 <a target="_blank" href="https://www.toptal.com/developers/css/sprite-generator">CSS Sprite Generator</a><br />👉 <a target="_blank" href="https://www.spritecow.com/">Sprite Cow</a></p>
<p><strong>V d:</strong> Gp 3 hnh nh <code>icon-home.png</code>, <code>icon-user.png</code>, <code>icon-search.png</code> vo mt nh <code>sprite.png</code>:</p>
<pre><code class="lang-javascript">sprite.png
-----------------
|  icon-home    |
|  icon-user    |
|  icon-search  |
-----------------
</code></pre>
<h4 id="heading-buoc-2-xac-dinh-vi-tri-tung-hinh-anh-trong-file-sprite"><strong>Bc 2: Xc nh v tr tng hnh nh trong file sprite</strong></h4>
<p>Sau khi c file <code>sprite.png</code>, bn cn xc nh ta  (X, Y) ca tng hnh nh bn trong file ny.</p>
<p><strong>V d:</strong></p>
<ul>
<li><p><code>icon-home.png</code> nm  v tr (0, 0)</p>
</li>
<li><p><code>icon-user.png</code> nm  v tr (0, 50px)</p>
</li>
<li><p><code>icon-search.png</code> nm  v tr (0, 100px)</p>
</li>
</ul>
<h4 id="heading-buoc-3-su-dung-css-de-hien-thi-hinh-anh"><strong>Bc 3: S dng CSS  hin th hnh nh</strong></h4>
<p>Bn c th s dng <code>background-position</code>  hin th tng hnh nh ring l t file sprite.</p>
<pre><code class="lang-css"><span class="hljs-selector-class">.sprite</span> {
    <span class="hljs-attribute">background-image</span>: <span class="hljs-built_in">url</span>(<span class="hljs-string">'sprite.png'</span>);
    <span class="hljs-attribute">background-repeat</span>: no-repeat;
    <span class="hljs-attribute">display</span>: inline-block;
    <span class="hljs-attribute">width</span>: <span class="hljs-number">50px</span>; <span class="hljs-comment">/* Kch thc icon */</span>
    <span class="hljs-attribute">height</span>: <span class="hljs-number">50px</span>;
}

<span class="hljs-selector-class">.icon-home</span> {
    <span class="hljs-attribute">background-position</span>: <span class="hljs-number">0</span> <span class="hljs-number">0</span>;
}

<span class="hljs-selector-class">.icon-user</span> {
    <span class="hljs-attribute">background-position</span>: <span class="hljs-number">0</span> -<span class="hljs-number">50px</span>;
}

<span class="hljs-selector-class">.icon-search</span> {
    <span class="hljs-attribute">background-position</span>: <span class="hljs-number">0</span> -<span class="hljs-number">100px</span>;
}
</code></pre>
<h4 id="heading-buoc-4-ap-dung-vao-html"><strong>Bc 4: p dng vo HTML</strong></h4>
<p>By gi, bn ch cn thm cc class vo HTML  hin th ng hnh nh:</p>
<pre><code class="lang-html"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"sprite icon-home"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"sprite icon-user"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"sprite icon-search"</span>&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span>
</code></pre>
<h3 id="heading-4-cong-cu-ho-tro-tao-css-sprite"><strong>4. Cng c h tr to CSS Sprite</strong></h3>
<p>Di y l mt s cng c gip bn to CSS Sprite nhanh chng:</p>
<ul>
<li><p><a target="_blank" href="https://www.toptal.com/developers/css/sprite-generator">CSS Sprite Generator</a></p>
</li>
<li><p><a target="_blank" href="https://www.spritecow.com/">Sprite Cow</a>  Gip ly ta  ca tng nh trong file sprite</p>
</li>
<li><p><a target="_blank" href="https://github.com/jorgebastida/glue">Glue</a>  Cng c mnh m  to sprite bng Python</p>
</li>
</ul>
<h3 id="heading-5-khi-nao-nen-su-dung-css-sprite"><strong>5. Khi no nn s dng CSS Sprite?</strong></h3>
<ul>
<li><p><strong>Website c nhiu icon nh</strong>: Nh menu, button, social media icon,...</p>
</li>
<li><p><strong>Mun ti u tc  ti trang</strong>: CSS Sprite gip gim thi gian ti trang ng k.</p>
</li>
<li><p><strong>Khng cn nh ng (GIF) hoc nh c  trong sut cao (PNG transparency)</strong>: V i khi sprite c th lm mt hiu ng trong sut ca nh PNG.</p>
</li>
</ul>
<h3 id="heading-6-luu-y-khi-dung-css-sprite"><strong>6. Lu  khi dng CSS Sprite</strong></h3>
<ul>
<li><p><strong>Khng ph hp vi nh ln hoc nh c nhiu mu sc khc nhau</strong>: CSS Sprite thch hp vi cc hnh nh nh, t chi tit hn.</p>
</li>
<li><p><strong>Cn cp nht ton b sprite khi thay i mt nh nh</strong>: Nu cn thay i mt icon trong sprite, bn phi cp nht li ton b file sprite.</p>
</li>
<li><p><strong>C th gy kh khn cho vic qun l m ngun</strong>: Khi c qu nhiu hnh nh trong mt sprite, vic tm v chnh sa c th mt nhiu thi gian.</p>
</li>
</ul>
<h3 id="heading-7-ket-luan"><strong>7. Kt lun</strong></h3>
<p>CSS Sprite l mt k thut ti u ha hnh nh cc k hiu qu gip gim HTTP request, tng tc  ti trang v ci thin hiu sut website. Nu bn ang qun l mt trang web c nhiu hnh nh nh, hy p dng CSS Sprite  gip trang ca bn nhanh hn v mt m hn.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/css-sprite-image-sprite-toi-uu-hoa-hinh-anh</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/css-sprite-image-sprite-toi-uu-hoa-hinh-anh</guid><category><![CDATA[#css-image-sprites]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Quản lý tài liệu hiệu quả với GetOutline]]></title><description><![CDATA[<h2 id="heading-getoutline-la-gi"><strong>GetOutline l g?</strong></h2>
<p><a target="_blank" href="https://www.getoutline.com/">GetOutline</a> l mt nn tng qun l ti liu m ngun m, gip cc i nhm, t chc chia s kin thc mt cch khoa hc. Cng c ny c thit k  thay th cc gii php truyn thng nh Google Docs hay Notion, nhng vi giao din ti gin, tc  nhanh v kh nng ty chnh mnh m.</p>
<p>Nu bn ang tm kim mt gii php  lu tr ti liu ni b, cng tc hiu qu v d dng truy xut thng tin, th GetOutline l la chn ng cn nhc.</p>
<h2 id="heading-nhung-tinh-nang-noi-bat"><strong>Nhng tnh nng ni bt</strong></h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740825098175/efa9083d-e824-4047-86f1-86b100e98d10.png" alt="Nhng tnh nng ni bt" class="image--center mx-auto" /></p>
<h3 id="heading-1-quan-ly-tai-lieu-khoa-hoc"><strong>1. Qun l ti liu khoa hc</strong></h3>
<p>GetOutline cho php bn to, sp xp v phn loi ti liu theo th mc hoc ch . Bn c th d dng ko th  sp xp li ti liu theo  mun.</p>
<h3 id="heading-2-giao-dien-don-gian-de-su-dung"><strong>2. Giao din n gin, d s dng</strong></h3>
<p>Khng qu cu k nh mt s nn tng khc, GetOutline tp trung vo tri nghim ngi dng vi giao din ti gin, trc quan, gip bn d dng to v chnh sa ti liu nhanh chng.</p>
<h3 id="heading-3-tim-kiem-thong-minh"><strong>3. Tm kim thng minh</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740824912813/fa45baee-4177-4496-af30-e5c31f872a5e.png" alt="Tm kim thng minh" class="image--center mx-auto" /></p>
<p>Vi tnh nng tm kim mnh m, bn c th tm thy ti liu mong mun trong tch tc, ngay c khi c hng trm ti liu khc nhau.</p>
<h3 id="heading-4-tich-hop-voi-cac-cong-cu-khac"><strong>4. Tch hp vi cc cng c khc</strong></h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740823853321/9cdf9d01-a80b-4917-9441-dda11c145df2.png" alt="Tch hp vi cc cng c khc" class="image--center mx-auto" /></p>
<p>GetOutline h tr tch hp vi Slack, Trello, Google v nhiu nn tng khc, gip bn d dng lm vic lin mch gia cc cng c.</p>
<h3 id="heading-5-phan-quyen-truy-cap-linh-hoat"><strong>5. Phn quyn truy cp linh hot</strong></h3>
<p>Bn c th kim sot ai c th xem, chnh sa hoc qun l ti liu. iu ny gip bo mt thng tin v trnh nhng chnh sa khng mong mun.</p>
<h3 id="heading-6-ho-tro-markdown"><strong>6. H tr markdown</strong></h3>
<p>Nu bn l ngi yu thch Markdown, GetOutline cung cp trnh son tho h tr c php ny, gip bn nh dng ti liu mt cch nhanh chng.</p>
<h3 id="heading-7-trien-khai-linh-hoat-cloud-amp-self-hosted"><strong>7. Trin khai linh hot (Cloud &amp; Self-hosted)</strong></h3>
<p>Bn c th s dng GetOutline trn m my (Cloud) hoc t trin khai trn my ch ca mnh  kim sot d liu mt cch tt nht.</p>
<h2 id="heading-loi-ich-khi-su-dung-getoutline"><strong>Li ch khi s dng GetOutline</strong></h2>
<p> <strong>Nng cao hiu sut lm vic nhm:</strong> Cc thnh vin c th d dng truy cp v cng tc trn ti liu.<br /> <strong>Tit kim thi gian tm kim:</strong> H thng tm kim thng minh gip bn nhanh chng tm thy thng tin cn thit.<br /> <strong>Bo mt d liu tt hn:</strong> Kim sot quyn truy cp gip bo v ti liu quan trng.<br /> <strong>Tch hp mt m vi cc cng c khc:</strong> Gip cng vic tr nn linh hot v hiu qu hn.</p>
<h2 id="heading-so-sanh-getoutline-voi-cac-cong-cu-khac"><strong>So snh GetOutline vi cc cng c khc</strong></h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td>Tnh Nng</td><td>GetOutline</td><td>Notion</td><td>Google Docs</td></tr>
</thead>
<tbody>
<tr>
<td>M ngun m</td><td> C</td><td> Khng</td><td> Khng</td></tr>
<tr>
<td>H tr Markdown</td><td> C</td><td> C</td><td> Khng</td></tr>
<tr>
<td>Tch hp Slack</td><td> C</td><td> C</td><td> Khng</td></tr>
<tr>
<td>Qun l ti liu ni b</td><td> C</td><td> C</td><td> C</td></tr>
<tr>
<td>Trin khai self-hosted</td><td> C</td><td> Khng</td><td> Khng</td></tr>
</tbody>
</table>
</div><p>Nh vy, nu bn cn mt cng c <strong>m ngun m</strong>, <strong>h tr Markdown</strong>, v c th <strong>trin khai t qun l</strong>, bo mt ti liu th GetOutline l mt la chn tuyt vi so vi Notion hay Google Docs.</p>
<h2 id="heading-doi-tuong-su-dung"><strong>i tng s dng</strong></h2>
<p>🔹 <strong>Doanh nghip &amp; Startup:</strong> Qun l ti liu ni b mt cch khoa hc.<br />🔹 <strong>Nhm pht trin phn mm:</strong> Tch hp vi Slack v h tr Markdown rt tin li.<br />🔹 <strong>C nhn mun ghi ch hiu qu:</strong> Giao din n gin, d s dng.<br />🔹 <strong>T chc gio dc &amp; nghin cu:</strong> D dng chia s ti liu v kin thc.</p>
<h2 id="heading-bat-dau-voi-getoutline"><strong>Bt u vi GetOutline</strong></h2>
<p>1 <strong>Truy cp trang web chnh thc</strong> ti <a target="_blank" href="https://www.getoutline.com/"><strong>getoutline.com</strong></a><br />2 <strong>To ti khon min ph</strong> hoc ti v phin bn self-hosted<br />3 <strong>Bt u to v qun l ti liu</strong><br />4 <strong>Tch hp vi cc cng c khc</strong>  ti u quy trnh lm vic</p>
<h2 id="heading-ket-luan"><strong>Kt lun</strong></h2>
<p>GetOutline l mt la chn tuyt vi nu bn ang tm kim mt cng c ghi ch v qun l ti liu mnh m, linh hot v d s dng. Vi nhng tnh nng nh h tr Markdown, phn quyn linh hot, tch hp vi Slack v kh nng t trin khai, n ph hp cho c c nhn, i nhm v doanh nghip.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/gioi-thieu-getoutline</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/gioi-thieu-getoutline</guid><category><![CDATA[documentation]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Chia sẻ template viết docs, API docs và blog cá nhân]]></title><description><![CDATA[<h2 id="heading-gioi-thieu">🔥 Gii thiu</h2>
<p><a target="_blank" href="https://docusaurus.io/">Docusaurus</a> l mt cng c to trang web tnh m ngun m da trn React, ni ting vi kh nng to ti liu, blog, trang web marketing v ng dng web mt trang mt cch nhanh chng v d dng. im mnh ca Docusaurus nm  giao din tch hp sn, ti liu chi tit, hng dn s dng, v cng ng ngi dng ln sn sng h tr.</p>
<p>Nu bn ang tm kim mt template hon chnh  bt u nhanh chng, th <strong>docusaurus-tailwind-shadcn-template</strong> l mt la chn tuyt vi.</p>
<p><strong>📌 Repo Github</strong>: <a target="_blank" href="https://github.com/namnguyenthanhwork/docusaurus-tailwind-shadcn-template">docusaurus-tailwind-shadcn-template</a></p>
<p>👉 <strong>Demo:</strong> <a target="_blank" href="https://docusaurus-tailwind-shadcn-template.vercel.app/">https://docusaurus-tailwind-shadcn-template.vercel.app/</a></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740239675603/11dc2872-e434-4d5b-9a7b-446ae94e7187.png" alt="template" class="image--center mx-auto" /></p>
<p><strong>Template ny tch hp</strong></p>
<ul>
<li><p> Docusaurus V3</p>
</li>
<li><p>🎨 TailwindCSS (H tr v3 &amp; v4)</p>
</li>
<li><p>🧩 Shadcn/UI</p>
</li>
<li><p>🔍 Tnh nng tm kim bi <code>@easyops-cn/docusaurus-search-local</code> plugin</p>
</li>
<li><p>📝 H tr t ng to API docs nh <code>@PaloAltoNetworks/docusaurus-openapi-docs</code> plugin</p>
</li>
<li><p>📱 Hon ton responsive</p>
</li>
<li><p>🌗 H tr chuyn theme sng/ti</p>
</li>
</ul>
<p>gip bn d dng ty chnh giao din, vit docs chuyn nghip, v m rng vi cc tnh nng mnh m.</p>
<h2 id="heading-tinh-nang-chinh">🎯 Tnh nng chnh</h2>
<p> <strong>H tr vit Docs &amp; API Docs</strong>: D dng to ti liu chuyn nghip.<br /> <strong>H thng Blog</strong>: Vit bi blog c nhn ngay trong Docusaurus.<br /> <strong>Giao din hin i</strong>: S dng TailwindCSS &amp; ShadCN UI.<br /> <strong>D dng ty chnh</strong>: Thay i theme, cu trc m khng cn qu nhiu chnh sa.<br /> <strong>Trin khai d dng</strong>: H tr deploy trn Vercel, Netlify, Cloudflare Pages...</p>
<h2 id="heading-cach-cai-dat-va-su-dung">🚀 Cch ci t v s dng</h2>
<h3 id="heading-1-clone-repository">1 Clone Repository</h3>
<p>Trc tin, bn cn clone repo v my:</p>
<pre><code class="lang-sh">git <span class="hljs-built_in">clone</span> https://github.com/namnguyenthanhwork/docusaurus-tailwind-shadcn-template.git
<span class="hljs-built_in">cd</span> docusaurus-tailwind-shadcn-template
</code></pre>
<p>Chn nhnh ph hp vi nhu cu s dng ca bn:</p>
<ul>
<li><p>Template Docusaurus (docs v blog) vi Tailwind v3: <code>feature/docusaurus-tailwind-v3</code></p>
</li>
<li><p>Template Docusaurus (docs, api docs v blog) vi Tailwind v3: <code>feature/docusaurus-tailwind-v3-openapi-docs</code></p>
</li>
<li><p>Template Docusaurus (docs v blog) vi Tailwind v4: <code>feature/docusaurus-tailwind-v4</code></p>
</li>
<li><p>Template Docusaurus (docs, api docs v blog) vi Tailwind v4: <code>feature/docusaurus-tailwind-v4-openapi-docs</code></p>
</li>
</ul>
<h3 id="heading-2-cai-dat-dependencies">2 Ci t Dependencies</h3>
<p>S dng <strong>npm</strong> hoc <strong>yarn</strong>  ci t cc package cn thit:</p>
<pre><code class="lang-sh">npm install
<span class="hljs-comment"># Hoc dng Yarn</span>
yarn install
</code></pre>
<h3 id="heading-3-chay-du-an">3 Chy d n</h3>
<p>Sau khi ci t xong, chy lnh sau  khi ng Docusaurus:</p>
<pre><code class="lang-sh">npm start
<span class="hljs-comment"># Hoc dng Yarn</span>
yarn start
</code></pre>
<p>M trnh duyt v truy cp <a target="_blank" href="http://localhost:3000/"><strong>http://localhost:3000/</strong></a>  xem kt qu.</p>
<h2 id="heading-cach-viet-docs-va-blog"> Cch vit docs v blog</h2>
<h3 id="heading-1-viet-tai-lieu-docs">1. Vit ti liu (Docs)</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740239714128/04d37ae3-9f32-4163-95ff-f75cdfd63c64.png" alt="docs" class="image--center mx-auto" /></p>
<p>Docs c lu trong th mc <strong>/docs</strong>.  thm ti liu mi:</p>
<ol>
<li><p>Vo th mc <strong>docs/</strong></p>
</li>
<li><p>To file <code>.md</code> hoc <code>.mdx</code></p>
</li>
<li><p>Thm ni dung Markdown</p>
</li>
</ol>
<h3 id="heading-2-viet-tai-lieu-api-api-docs">2. Vit ti liu API (API Docs)</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740239720769/b4e13387-85c8-418d-b198-71005aa42653.png" alt="api docs" class="image--center mx-auto" /></p>
<p>Template c tch hp plugin <a target="_blank" href="https://github.com/PaloAltoNetworks/docusaurus-openapi-docs">docusaurus-plugin-openapi-docs</a> gip t ng to API docs da vo 1 file <code>.yaml</code></p>
<p>Cch cu hnh bn c th tham kho  <a target="_blank" href="https://docusaurus-openapi.tryingpan.dev/">https://docusaurus-openapi.tryingpan.dev/</a></p>
<h3 id="heading-3-viet-blog">3. Vit blog</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1740239763271/66382368-4a84-4a66-8716-8c91a5389f47.png" alt="blog" class="image--center mx-auto" /></p>
<p>Cc bi vit blog nm trong th mc <strong>/blog</strong>.  to bi vit mi:</p>
<ol>
<li><p>Vo th mc <strong>blog/</strong></p>
</li>
<li><p>To file <code>.md</code> hoc <code>.mdx</code></p>
</li>
<li><p>Vit ni dung</p>
</li>
</ol>
<h2 id="heading-tuy-chinh-giao-dien">🎨 Tu chnh giao din</h2>
<p><strong>Chnh sa mu sc trong Tailwind</strong></p>
<ul>
<li><p>Trong <strong>Tailwind v3</strong>, cp nht trong <code>tailwind.config.js</code>.</p>
</li>
<li><p>Trong <strong>Tailwind v4</strong>, chnh sa trong <code>src/css/custom.css</code>.</p>
</li>
<li><p>Cp nht bin CSS trong <code>src/css/custom.css</code>.</p>
</li>
</ul>
<p><strong>Ty chnh cc component ca Shadcn/UI</strong></p>
<ul>
<li>Chnh sa cc thnh phn trong th mc <code>src/components/ui/</code>.</li>
</ul>
<p><strong>V d:</strong></p>
<p>To mt button ty chnh trong <strong>Docusaurus</strong>:</p>
<pre><code class="lang-tsx">// src/components/ui/custom-button.tsx
import { Button } from './button';

export function CustomButton({ children }) {
  return (
    &lt;Button className="custom-styles"&gt;
      {children}
    &lt;/Button&gt;
  );
}
</code></pre>
<p><strong>Ghi  cc component ca Docusaurus</strong></p>
<p>Bn c th ghi  cc component bng cch <strong>Swizzling</strong>. Xem thm v <a target="_blank" href="https://docusaurus.io/docs/swizzling"><strong>Component Swizzling.</strong></a></p>
<h2 id="heading-ket-luan">🎯 Kt lun</h2>
<p>Nu bn ang tm kim mt template chuyn nghip  vit ti liu, API docs hoc blog c nhn, <strong>docusaurus-tailwind-shadcn-template</strong> l mt la chn tuyt vi. Vi Docusaurus, TailwindCSS v ShadCN UI, bn c th to mt trang web ti liu chuyn nghip m khng cn qu nhiu cng sc.</p>
<p>👉 <strong>Dng th ngay</strong>: <a target="_blank" href="https://github.com/namnguyenthanhwork/docusaurus-tailwind-shadcn-template">GitHub Repo</a></p>
<p>🔗 <strong>Ti nguyn tham kho</strong>:</p>
<ul>
<li><p><a target="_blank" href="https://docusaurus.io/docs">Docusaurus Docs</a></p>
</li>
<li><p><a target="_blank" href="https://tailwindcss.com/docs/installation/using-vite">TailwindCSS Docs</a></p>
</li>
<li><p><a target="_blank" href="https://ui.shadcn.com/">ShadCN/UI</a></p>
</li>
<li><p><a target="_blank" href="https://docusaurus-openapi.tryingpan.dev/"><strong>OpenAPI Docs</strong></a></p>
</li>
</ul>
<p> Chc bn thnh cng! 🎉</p>
]]></description><link>https://blog.thanhnamnguyen.dev/chia-se-template-viet-docs-api-docs-va-blog-ca-nhan</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/chia-se-template-viet-docs-api-docs-va-blog-ca-nhan</guid><category><![CDATA[docusaurus]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[shadcn]]></category><category><![CDATA[APIDocumentation]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Tích hợp TailwindCSS và Shadcn/UI vào Docusaurus]]></title><description><![CDATA[<p><a target="_blank" href="https://docusaurus.io/">Docusaurus</a> - mt cng c to trang web tnh m ngun m da trn React, ni ting vi kh nng to ti liu, blog, trang web marketing v ng dng web mt trang mt cch nhanh chng v d dng. im mnh ca Docusaurus nm  giao din tch hp sn, ti liu chi tit, hng dn s dng, v cng ng ngi dng ln sn sng h tr.</p>
<p>Kt hp vi <a target="_blank" href="https://tailwindcss.com/"><strong>TailwindCSS</strong></a> l mt framework CSS tin dng, tp trung vo vic cung cp cc utility classes (lp tin ch)  bn d dng xy dng giao din m khng cn vit qu nhiu CSS ty chnh. Khc vi cc framework truyn thng nh Bootstrap, Tailwind khng cung cp cc thnh phn sn c, thay vo , bn s t do "xy dng mi th" da trn cc utility classes nh <code>bg-blue-500</code>, <code>text-center</code>, hoc <code>flex</code>.</p>
<p><strong>Shadcn/UI</strong> l mt th vin giao din hin i c xy dng da trn <strong>TailwindCSS</strong>. Thay v ch cung cp cc lp tin ch, Shadcn/UI mang n cc thnh phn (components) sn c nh Button, Input, Dropdown, Modal,... vi thit k p mt, c th d dng ty chnh v m rng.</p>
<p>S kt hp ny gip bn to ra cc trang web v ng dng web khng ch p mt, hin i m cn d s dng, mang n tri nghim tuyt vi cho ngi dng.</p>
<p>Hy cng tham kho bi vit di y  tch hp TailwindCSS v Shadcn/UI vo Docusaurus.</p>
<h2 id="heading-thiet-lap-ban-dau">Thit lp ban u</h2>
<p>V Shadcn/UI c khng c xy dng cho Docusaurus nn chng ta s cn thc hin mt s iu chnh  n hot ng vi Docusaurus.</p>
<p>u tin, hy to mt d n Docusaurus mi nu bn cha c:</p>
<pre><code class="lang-bash">npx create-docusaurus@latest my-website classic
<span class="hljs-built_in">cd</span> my-website
</code></pre>
<p>Ci t cc ph thuc cn thit:</p>
<pre><code class="lang-bash">npm install tailwindcss tailwindcss-animate postcss autoprefixer class-variance-authority tailwind-merge lucide-react
</code></pre>
<h2 id="heading-cau-hinh-tailwind-css">Cu hnh Tailwind CSS</h2>
<p>To file <code>tailwind.config.js</code>  th mc gc ca d n:</p>
<pre><code class="lang-javascript"><span class="hljs-comment">/** <span class="hljs-doctag">@type <span class="hljs-type">{import('tailwindcss').Config}</span> </span>*/</span>
<span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">content</span>: [
    <span class="hljs-string">'./src/**/*.{js,jsx,ts,tsx}'</span>,
    <span class="hljs-string">'./docs/**/*.{js,jsx,ts,tsx}'</span>,
    <span class="hljs-string">'./blog/**/*.{js,jsx,ts,tsx}'</span>
  ],
  <span class="hljs-attr">darkMode</span>: [<span class="hljs-string">'class'</span>, <span class="hljs-string">'[data-theme="dark"]'</span>], <span class="hljs-comment">// Support Docusaurus dark mode</span>
  <span class="hljs-attr">theme</span>: {
    <span class="hljs-attr">extend</span>: {
      <span class="hljs-attr">colors</span>: {
        <span class="hljs-attr">border</span>: <span class="hljs-string">'hsl(var(--border))'</span>,
        <span class="hljs-attr">input</span>: <span class="hljs-string">'hsl(var(--input))'</span>,
        <span class="hljs-attr">ring</span>: <span class="hljs-string">'hsl(var(--ring))'</span>,
        <span class="hljs-attr">background</span>: <span class="hljs-string">'hsl(var(--background))'</span>,
        <span class="hljs-attr">foreground</span>: <span class="hljs-string">'hsl(var(--foreground))'</span>,
        <span class="hljs-attr">primary</span>: {
          <span class="hljs-attr">DEFAULT</span>: <span class="hljs-string">'hsl(var(--primary))'</span>,
          <span class="hljs-attr">foreground</span>: <span class="hljs-string">'hsl(var(--primary-foreground))'</span>
        },
        <span class="hljs-attr">secondary</span>: {
          <span class="hljs-attr">DEFAULT</span>: <span class="hljs-string">'hsl(var(--secondary))'</span>,
          <span class="hljs-attr">foreground</span>: <span class="hljs-string">'hsl(var(--secondary-foreground))'</span>
        },
        <span class="hljs-attr">destructive</span>: {
          <span class="hljs-attr">DEFAULT</span>: <span class="hljs-string">'hsl(var(--destructive))'</span>,
          <span class="hljs-attr">foreground</span>: <span class="hljs-string">'hsl(var(--destructive-foreground))'</span>
        },
        <span class="hljs-attr">muted</span>: {
          <span class="hljs-attr">DEFAULT</span>: <span class="hljs-string">'hsl(var(--muted))'</span>,
          <span class="hljs-attr">foreground</span>: <span class="hljs-string">'hsl(var(--muted-foreground))'</span>
        },
        <span class="hljs-attr">accent</span>: {
          <span class="hljs-attr">DEFAULT</span>: <span class="hljs-string">'hsl(var(--accent))'</span>,
          <span class="hljs-attr">foreground</span>: <span class="hljs-string">'hsl(var(--accent-foreground))'</span>
        },
        <span class="hljs-attr">popover</span>: {
          <span class="hljs-attr">DEFAULT</span>: <span class="hljs-string">'hsl(var(--popover))'</span>,
          <span class="hljs-attr">foreground</span>: <span class="hljs-string">'hsl(var(--popover-foreground))'</span>
        },
        <span class="hljs-attr">card</span>: {
          <span class="hljs-attr">DEFAULT</span>: <span class="hljs-string">'hsl(var(--card))'</span>,
          <span class="hljs-attr">foreground</span>: <span class="hljs-string">'hsl(var(--card-foreground))'</span>
        }
      },
      <span class="hljs-attr">borderRadius</span>: {
        <span class="hljs-attr">lg</span>: <span class="hljs-string">`var(--radius)`</span>,
        <span class="hljs-attr">md</span>: <span class="hljs-string">`calc(var(--radius) - 2px)`</span>,
        <span class="hljs-attr">sm</span>: <span class="hljs-string">'calc(var(--radius) - 4px)'</span>
      }
    }
  },
  <span class="hljs-attr">plugins</span>: [<span class="hljs-built_in">require</span>(<span class="hljs-string">'tailwindcss-animate'</span>)]
}
</code></pre>
<p>To file <code>postcss.config.js</code></p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = {
  <span class="hljs-attr">plugins</span>: {
    <span class="hljs-attr">tailwindcss</span>: {},
    <span class="hljs-attr">autoprefixer</span>: {}
  }
}
</code></pre>
<h2 id="heading-thiet-lap-css">Thit lp CSS</h2>
<p>To file <code>src/css/custom.css</code> hoc chnh sa nu tn ti, y l ni bn to theme ca Shadcn/UI.</p>
<pre><code class="lang-css"><span class="hljs-keyword">@tailwind</span> base;
<span class="hljs-keyword">@tailwind</span> components;
<span class="hljs-keyword">@tailwind</span> utilities;

<span class="hljs-keyword">@layer</span> base {
  <span class="hljs-selector-pseudo">:root</span> {
    <span class="hljs-attribute">--background</span>: <span class="hljs-number">0</span> <span class="hljs-number">0%</span> <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">--foreground</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">84%</span> <span class="hljs-number">4.9%</span>;
    <span class="hljs-attribute">--card</span>: <span class="hljs-number">0</span> <span class="hljs-number">0%</span> <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">--card-foreground</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">84%</span> <span class="hljs-number">4.9%</span>;
    <span class="hljs-attribute">--popover</span>: <span class="hljs-number">0</span> <span class="hljs-number">0%</span> <span class="hljs-number">100%</span>;
    <span class="hljs-attribute">--popover-foreground</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">84%</span> <span class="hljs-number">4.9%</span>;
    <span class="hljs-attribute">--primary</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">47.4%</span> <span class="hljs-number">11.2%</span>;
    <span class="hljs-attribute">--primary-foreground</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">98%</span>;
    <span class="hljs-attribute">--secondary</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">96.1%</span>;
    <span class="hljs-attribute">--secondary-foreground</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">47.4%</span> <span class="hljs-number">11.2%</span>;
    <span class="hljs-attribute">--muted</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">96.1%</span>;
    <span class="hljs-attribute">--muted-foreground</span>: <span class="hljs-number">215.4</span> <span class="hljs-number">16.3%</span> <span class="hljs-number">46.9%</span>;
    <span class="hljs-attribute">--accent</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">96.1%</span>;
    <span class="hljs-attribute">--accent-foreground</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">47.4%</span> <span class="hljs-number">11.2%</span>;
    <span class="hljs-attribute">--destructive</span>: <span class="hljs-number">0</span> <span class="hljs-number">84.2%</span> <span class="hljs-number">60.2%</span>;
    <span class="hljs-attribute">--destructive-foreground</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">98%</span>;
    <span class="hljs-attribute">--border</span>: <span class="hljs-number">214.3</span> <span class="hljs-number">31.8%</span> <span class="hljs-number">91.4%</span>;
    <span class="hljs-attribute">--input</span>: <span class="hljs-number">214.3</span> <span class="hljs-number">31.8%</span> <span class="hljs-number">91.4%</span>;
    <span class="hljs-attribute">--ring</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">84%</span> <span class="hljs-number">4.9%</span>;
    <span class="hljs-attribute">--radius</span>: <span class="hljs-number">0.5rem</span>;
  }

  <span class="hljs-selector-tag">html</span><span class="hljs-selector-attr">[data-theme=<span class="hljs-string">'dark'</span>]</span> {
    <span class="hljs-attribute">--background</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">84%</span> <span class="hljs-number">4.9%</span>;
    <span class="hljs-attribute">--foreground</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">98%</span>;
    <span class="hljs-attribute">--card</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">84%</span> <span class="hljs-number">4.9%</span>;
    <span class="hljs-attribute">--card-foreground</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">98%</span>;
    <span class="hljs-attribute">--popover</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">84%</span> <span class="hljs-number">4.9%</span>;
    <span class="hljs-attribute">--popover-foreground</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">98%</span>;
    <span class="hljs-attribute">--primary</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">98%</span>;
    <span class="hljs-attribute">--primary-foreground</span>: <span class="hljs-number">222.2</span> <span class="hljs-number">47.4%</span> <span class="hljs-number">11.2%</span>;
    <span class="hljs-attribute">--secondary</span>: <span class="hljs-number">217.2</span> <span class="hljs-number">32.6%</span> <span class="hljs-number">17.5%</span>;
    <span class="hljs-attribute">--secondary-foreground</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">98%</span>;
    <span class="hljs-attribute">--muted</span>: <span class="hljs-number">217.2</span> <span class="hljs-number">32.6%</span> <span class="hljs-number">17.5%</span>;
    <span class="hljs-attribute">--muted-foreground</span>: <span class="hljs-number">215</span> <span class="hljs-number">20.2%</span> <span class="hljs-number">65.1%</span>;
    <span class="hljs-attribute">--accent</span>: <span class="hljs-number">217.2</span> <span class="hljs-number">32.6%</span> <span class="hljs-number">17.5%</span>;
    <span class="hljs-attribute">--accent-foreground</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">98%</span>;
    <span class="hljs-attribute">--destructive</span>: <span class="hljs-number">0</span> <span class="hljs-number">62.8%</span> <span class="hljs-number">30.6%</span>;
    <span class="hljs-attribute">--destructive-foreground</span>: <span class="hljs-number">210</span> <span class="hljs-number">40%</span> <span class="hljs-number">98%</span>;
    <span class="hljs-attribute">--border</span>: <span class="hljs-number">217.2</span> <span class="hljs-number">32.6%</span> <span class="hljs-number">17.5%</span>;
    <span class="hljs-attribute">--input</span>: <span class="hljs-number">217.2</span> <span class="hljs-number">32.6%</span> <span class="hljs-number">17.5%</span>;
    <span class="hljs-attribute">--ring</span>: <span class="hljs-number">212.7</span> <span class="hljs-number">26.8%</span> <span class="hljs-number">83.9%</span>;
  }
}
</code></pre>
<h2 id="heading-tao-thu-muc-utils">To th mc Utils</h2>
<p>To <code>src/lib/utils.ts</code></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> { clsx, type ClassValue } <span class="hljs-keyword">from</span> <span class="hljs-string">"clsx"</span>
<span class="hljs-keyword">import</span> { twMerge } <span class="hljs-keyword">from</span> <span class="hljs-string">"tailwind-merge"</span>

<span class="hljs-keyword">export</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">cn</span>(<span class="hljs-params">...inputs: ClassValue[]</span>) </span>{
  <span class="hljs-keyword">return</span> twMerge(clsx(inputs))
}
</code></pre>
<h2 id="heading-tao-shadcnui-components">To Shadcn/UI Components</h2>
<p><strong> Lu :</strong> do Shadcn/ui khng xy dng dnh cho Docusaurus nn bn khng th ti cc component bng CLI, thay vo  l bn sao chp cc component mt cch th cng.</p>
<p>Cc bc thm bao gm:</p>
<ul>
<li><p>To mt th mc cha component: <code>src/components/ui</code></p>
</li>
<li><p>Copy cc component trn <a target="_blank" href="https://ui.shadcn.com/docs/components/accordion">Shadcn/ui</a>.</p>
</li>
<li><p>iu chnh ng dn import cho ph hp v ti cc packages nu component yu cu.</p>
</li>
</ul>
<p>V d: Button component (<code>src/components/ui/button.tsx</code>)</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> * <span class="hljs-keyword">as</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>
<span class="hljs-keyword">import</span> { Slot } <span class="hljs-keyword">from</span> <span class="hljs-string">'@radix-ui/react-slot'</span>
<span class="hljs-keyword">import</span> { cva, type VariantProps } <span class="hljs-keyword">from</span> <span class="hljs-string">'class-variance-authority'</span>

<span class="hljs-keyword">import</span> { cn } <span class="hljs-keyword">from</span> <span class="hljs-string">'../../lib/utils'</span>

<span class="hljs-keyword">const</span> buttonVariants = cva(
  <span class="hljs-string">'inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50 [&amp;_svg]:pointer-events-none [&amp;_svg]:size-4 [&amp;_svg]:shrink-0'</span>,
  {
    <span class="hljs-attr">variants</span>: {
      <span class="hljs-attr">variant</span>: {
        <span class="hljs-attr">default</span>: <span class="hljs-string">'bg-primary text-primary-foreground shadow hover:bg-primary/90'</span>,
        <span class="hljs-attr">destructive</span>: <span class="hljs-string">'bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90'</span>,
        <span class="hljs-attr">outline</span>:
          <span class="hljs-string">'border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground'</span>,
        <span class="hljs-attr">secondary</span>: <span class="hljs-string">'bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80'</span>,
        <span class="hljs-attr">ghost</span>: <span class="hljs-string">'hover:bg-accent hover:text-accent-foreground'</span>,
        <span class="hljs-attr">link</span>: <span class="hljs-string">'text-primary underline-offset-4 hover:underline'</span>
      },
      <span class="hljs-attr">size</span>: {
        <span class="hljs-attr">default</span>: <span class="hljs-string">'h-9 px-4 py-2'</span>,
        <span class="hljs-attr">sm</span>: <span class="hljs-string">'h-8 rounded-md px-3 text-xs'</span>,
        <span class="hljs-attr">lg</span>: <span class="hljs-string">'h-10 rounded-md px-8'</span>,
        <span class="hljs-attr">icon</span>: <span class="hljs-string">'h-9 w-9'</span>
      }
    },
    <span class="hljs-attr">defaultVariants</span>: {
      <span class="hljs-attr">variant</span>: <span class="hljs-string">'default'</span>,
      <span class="hljs-attr">size</span>: <span class="hljs-string">'default'</span>
    }
  }
)

<span class="hljs-keyword">export</span> interface ButtonProps
  <span class="hljs-keyword">extends</span> React.ButtonHTMLAttributes&lt;HTMLButtonElement&gt;,
    VariantProps&lt;<span class="hljs-keyword">typeof</span> buttonVariants&gt; {
  asChild?: boolean
}

<span class="hljs-keyword">const</span> Button = React.forwardRef&lt;HTMLButtonElement, ButtonProps&gt;(
  <span class="hljs-function">(<span class="hljs-params">{ className, variant, size, asChild = <span class="hljs-literal">false</span>, ...props }, ref</span>) =&gt;</span> {
    <span class="hljs-keyword">const</span> Comp = asChild ? Slot : <span class="hljs-string">'button'</span>
    <span class="hljs-keyword">return</span> (
      <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">Comp</span> <span class="hljs-attr">className</span>=<span class="hljs-string">{cn(buttonVariants({</span> <span class="hljs-attr">variant</span>, <span class="hljs-attr">size</span>, <span class="hljs-attr">className</span> }))} <span class="hljs-attr">ref</span>=<span class="hljs-string">{ref}</span> {<span class="hljs-attr">...props</span>} /&gt;</span></span>
    )
  }
)
Button.displayName = <span class="hljs-string">'Button'</span>

<span class="hljs-keyword">export</span> { Button, buttonVariants }
</code></pre>
<h2 id="heading-tao-plugin-tailwind-css">To plugin Tailwind CSS</h2>
<p>To file cu hnh Tailwind trong <code>src/plugins/tailwind-config.js</code></p>
<pre><code class="lang-javascript"><span class="hljs-built_in">module</span>.exports = <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">tailwindPlugin</span>(<span class="hljs-params">context, options</span>) </span>{
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">name</span>: <span class="hljs-string">'tailwind-plugin'</span>,
    configurePostCss(postcssOptions) {
      postcssOptions.plugins = [
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'postcss-import'</span>),
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'tailwindcss'</span>),
        <span class="hljs-built_in">require</span>(<span class="hljs-string">'autoprefixer'</span>)
      ]
      <span class="hljs-keyword">return</span> postcssOptions
    }
  }
}
</code></pre>
<h2 id="heading-cap-nhat-cau-hinh-docusaurus">Cp nht cu hnh Docusaurus</h2>
<p>iu chnh file <code>docusaurus.config.js</code>, thm plugin Tailwind bn va to.</p>
<pre><code class="lang-javascript">plugins: [
    [<span class="hljs-string">'./src/plugins/tailwind-config.js'</span>, {}],
]
</code></pre>
<h2 id="heading-su-dung">S dng</h2>
<p>By gi bn c th s dng cc components ca Shadcn/ui trong d n Docusaurus ca mnh.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> { Button } <span class="hljs-keyword">from</span> <span class="hljs-string">'../components/ui/button'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">className</span>=<span class="hljs-string">"p-4"</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Button</span>&gt;</span>Click me<span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">variant</span>=<span class="hljs-string">"destructive"</span>&gt;</span>Delete<span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Button</span> <span class="hljs-attr">variant</span>=<span class="hljs-string">"outline"</span>&gt;</span>Settings<span class="hljs-tag">&lt;/<span class="hljs-name">Button</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<h2 id="heading-demo">Demo</h2>
<p>Bn c th thao kho repo <a target="_blank" href="https://github.com/namnguyenthanhwork/docusaurus-tailwind-shadcn-template">docusaurus-tailwind-shadcn-template</a> m mnh  to. Trong d n ny  tch hp TailwindCSS &amp; Shadcn/UI vo Docusaurus. Bn cnh , mnh  custom li giao din, to 1 plugin gip em blog hin th  ngoi homepage.</p>
<p>👉 Xem thng tin chi tit repo  <a target="_blank" href="https://github.com/namnguyenthanhwork/docusaurus-tailwind-shadcn-template#readme">README.md</a></p>
<p><strong>📌 Repository:</strong> <a target="_blank" href="https://github.com/namnguyenthanhwork/docusaurus-tailwind-shadcn-template">https://github.com/namnguyenthanhwork/docusaurus-tailwind-shadcn-template</a></p>
<p><strong>🚀 Demo:</strong> <a target="_blank" href="https://docusaurus-tailwind-shadcn-template.vercel.app/">https://docusaurus-tailwind-shadcn-template.vercel.app/</a></p>
<p>Hy ng h 1  nu bn yu thch n. Cm n nh </p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736846204558/525b1f34-0e36-4c2c-a199-3d6b78ef1ece.png" alt="homepage" class="image--center mx-auto" /></p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736846260694/1f43755a-66d9-408a-8449-0a56b60e21f3.png" alt="blog page" class="image--center mx-auto" /></p>
]]></description><link>https://blog.thanhnamnguyen.dev/tich-hop-tailwindcss-va-shadcn-ui-vao-docusaurus</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/tich-hop-tailwindcss-va-shadcn-ui-vao-docusaurus</guid><category><![CDATA[docusaurus]]></category><category><![CDATA[Tailwind CSS]]></category><category><![CDATA[shadcn ui]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Jam.dev - Công cụ hiệu quả cho việc tái tạo lỗi]]></title><description><![CDATA[<h2 id="heading-tai-tao-loi-reproduce-la-gi">Ti to li (Reproduce) l g?</h2>
<p>Ti to li (reproduce) l mt bc quan trng trong qu trnh sa li phn mm. Khi ngi dng hoc tester bo co li, i ng lp trnh cn thc hin li cc bc chnh xc hoc thit lp mi trng ging nh ngi bo co  li xut hin ln na. iu ny gip xc minh li thc s tn ti v cung cp thng tin y   gii quyt vn .</p>
<p>Tuy nhin, vic ti to li c th tr nn phc tp nu thiu thng tin chi tit. y chnh l lc <a target="_blank" href="http://jam.dev"><strong>Jam.dev</strong></a> tr thnh cng c c lc gip qu trnh ny tr nn nhanh chng v d dng hn.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736159170379/bdd350b9-4915-4be2-bbaa-ab7fb183d71e.png" alt="jamdev" class="image--center mx-auto" /></p>
<h2 id="heading-tai-sao-jamdev-la-cong-cu-ho-tro-de-reproduce-loi">Ti sao Jam.dev l cng c h tr  reproduce li?</h2>
<p><a target="_blank" href="http://jam.dev"><strong>Jam.dev</strong></a> c thit k c bit  ti u ha qu trnh bo co v ti to li. Thay v mt hng gi trao i vi tester hoc ngi dng  thu thp thng tin, <strong>Jam.dev</strong> t ng ghi nhn mi d liu quan trng ngay khi li xy ra. iu ny gip lp trnh vin khng ch d dng reproduce li m cn tit kim rt nhiu thi gian.</p>
<h2 id="heading-jam-la-gi">Jam l g?</h2>
<p><strong>Vi Jam, ch vi mt c nhp chut, bn c th:</strong> chp nh mn hnh, quay video hoc ghi li ngay lp tc v Jam s ngay lp tc to mt lin kt  chia s vi nhm ca bn.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736159645041/bcc4f3dc-a454-4bfc-b1bf-1dc37807d9f8.png" alt="info" class="image--center mx-auto" /></p>
<p>Khi s dng Jam, chng s ghi nhn tt c thng tin chn on k thut m nhm k thut ca bn cn  g li nhanh chng, chng hn nh yu cu mng, nht k giao din iu khin, thng tin thit b v thm ch tc  mng! Tt c u c ghi li  bn khng cn phi ti to hoc tm kim chn on k thut trc khi bo co li.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736159890274/ff30829e-fdaf-4a51-b304-0f8f3273583a.png" alt="actions" class="image--center mx-auto" /></p>
<h4 id="heading-cac-tinh-nang-noi-bat-cua-jamdev-trong-qua-trinh-reproduce">Cc tnh nng ni bt ca Jam.dev trong qu trnh reproduce:</h4>
<ol>
<li><p><strong>Ghi nhn y  thng tin k thut</strong></p>
<ul>
<li><p>nh chp mn hnh hoc video li.</p>
</li>
<li><p>Log console chi tit.</p>
</li>
<li><p>D liu mng (Network logs).</p>
</li>
<li><p>Thng tin h thng nh trnh duyt, h iu hnh, v phin bn phn mm.</p>
</li>
</ul>
</li>
<li><p><strong>Bo co li ch trong mt c nhp chut</strong><br /> Tester hoc ngi dng ch cn nhn nt "Jam" trn tin ch m rng ca trnh duyt, v bo co li c t ng gi km theo y  thng tin cn thit.</p>
</li>
<li><p><strong>Tch hp vi cc cng c ph bin</strong><br /> <strong>Jam.dev</strong> d dng tch hp vi <strong>Jira, Trello, Slack</strong>, gip i ng pht trin c th x l li trong cc nn tng m h quen thuc.</p>
</li>
<li><p><strong>T ng chuyn giao mi trng:</strong><br /> Khi lp trnh vin nhn c bo co li t <strong>Jam.dev</strong>, h c th nhanh chng ti to li trong mi trng c thit lp ging ht vi mi trng m li xy ra.</p>
</li>
</ol>
<h2 id="heading-quy-trinh-reproduce-loi-voi-jamdev">Quy trnh Reproduce li vi Jam.dev</h2>
<h3 id="heading-buoc-1-cai-dat-jamdev">Bc 1: Ci t Jam.dev</h3>
<p>u tin, ci t tin ch m rng Jam.dev trn trnh duyt ca bn. Bn c th ti v ti Jam.dev.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736160064673/98306982-c9fa-4aea-b183-1fbd6407487c.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-buoc-2-bao-cao-loi">Bc 2: Bo co li</h3>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1736160108566/4e120b2f-1225-4796-b1bd-a0389eaf2c0d.png" alt class="image--center mx-auto" /></p>
<p>Khi mt tester hoc ngi dng gp li, h ch cn nhn vo biu tng Jam trn trnh duyt. Cng c ny s:</p>
<ul>
<li><p>Chp li nh mn hnh ca li.</p>
</li>
<li><p>Ghi nhn thng tin log console.</p>
</li>
<li><p>Lu tr d liu mng v thng tin h thng.</p>
</li>
</ul>
<h3 id="heading-buoc-3-tich-hop-voi-cac-cong-cu-quan-ly-du-an">Bc 3: Tch hp vi cc cng c qun l d n</h3>
<p>Bo co li t Jam.dev s c t ng gi n cc cng c qun l d n nh <strong>Jira, Trello, hoc Slack</strong>, ni i ng pht trin c th d dng truy cp v x l.</p>
<h3 id="heading-buoc-4-tai-tao-loi-reproduce">Bc 4: Ti to li (Reproduce)</h3>
<p>Khi lp trnh vin nhn c bo co li t Jam.dev, h c th s dng d liu chi tit  ti to li li, bao gm:</p>
<ul>
<li><p>Lm theo cc bc trong bo co.</p>
</li>
<li><p>Kim tra log console v d liu mng  hiu r nguyn nhn.</p>
</li>
<li><p>Th nghim trn mi trng ging nh trong bo co  xc minh vn .</p>
</li>
</ul>
<h3 id="heading-buoc-5-sua-loi-fix-bug">Bc 5: Sa li (Fix bug)</h3>
<p>Sau khi ti to li thnh cng, lp trnh vin c th nhanh chng xc nh nguyn nhn v trin khai bn sa li (patch).</p>
<h2 id="heading-loi-ich-cua-jamdev-trong-qua-trinh-reproduce">Li ch ca Jam.dev trong qu trnh Reproduce</h2>
<ol>
<li><p><strong>Tit kim thi gian</strong></p>
<ul>
<li><p>Khng cn yu cu thm thng tin t ngi bo co li.</p>
</li>
<li><p>Lp trnh vin c th bt u lm vic ngay lp tc vi d liu chi tit.</p>
</li>
</ul>
</li>
<li><p><strong>Gim thiu sai st</strong></p>
<ul>
<li><strong>Jam.dev</strong> t ng ghi nhn ton b d liu quan trng, trnh trng hp ngi dng hoc tester qun cung cp thng tin cn thit.</li>
</ul>
</li>
<li><p><strong>Ci thin giao tip gia cc i ng</strong></p>
<ul>
<li>Bo co li r rng v d hiu, gip gim thi gian trao i gia tester v lp trnh vin.</li>
</ul>
</li>
<li><p><strong>Ti to li trn nhiu mi trng:</strong></p>
<ul>
<li><strong>Jam.dev</strong> cho php lp trnh vin d dng kim tra li trn cc mi trng ging ht nh mi trng xy ra li (nh trnh duyt c th hoc phin bn h iu hnh).</li>
</ul>
</li>
</ol>
<h2 id="heading-vi-du-thuc-te-ve-su-dung-jamdev-de-reproduce-loi">V d thc t v s dng Jam.dev  Reproduce li</h2>
<h4 id="heading-tinh-huong-gia-dinh">🧑💻 Tnh hung gi nh:</h4>
<p>Mt ngi dng bo co rng trang web b crash khi h nhp vo nt "ng k".</p>
<h4 id="heading-bat-dau-quy-trinh-voi-jamdev">Bt u quy trnh vi Jam.dev</h4>
<ol>
<li><p>Ngi dng nhn vo nt "Jam"  bo co li.</p>
</li>
<li><p>Jam.dev t ng ghi nhn</p>
<ul>
<li><p>nh chp mn hnh lc trang web crash.</p>
</li>
<li><p>Log console vi chi tit li JavaScript.</p>
</li>
<li><p>D liu mng v cc API c gi ti thi im li.</p>
</li>
<li><p>Thng tin trnh duyt v h iu hnh.</p>
</li>
</ul>
</li>
<li><p>Bo co li c gi n <strong>Jira</strong>, ni lp trnh vin nhn c y  thng tin.</p>
</li>
<li><p>Lp trnh vin ti bo co t Jam.dev, kim tra log console, v th li trn trnh duyt ca h. Sau khi lm theo cc bc trong bo co, h ti to c li v bt tay vo sa.</p>
</li>
</ol>
<h2 id="heading-ket-luan">Kt lun</h2>
<p>Vic ti to li (reproduce) l mt phn quan trng trong quy trnh sa li, v <strong>Jam.dev</strong>  gip n gin ha cng vic ny n mc ti a. Vi cc tnh nng nh t ng thu thp d liu, tch hp cng c qun l d n, v h tr lp trnh vin ti to li chnh xc, <strong>Jam.dev</strong> khng ch tit kim thi gian m cn nng cao hiu qu lm vic ca nhm.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/jamdev-cong-cu-hieu-qua-cho-viec-tai-tao-loi</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/jamdev-cong-cu-hieu-qua-cho-viec-tai-tao-loi</guid><category><![CDATA[#Reproduce]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Kho tài nguyên miễn phí dành cho lập trình viên]]></title><description><![CDATA[<p>Bi vit ny s cung cp ci nhn tng quan v <a target="_blank" href="https://free-for.dev/">free-for.dev</a>, nhn mnh cc tnh nng chnh, cc danh mc ti nguyn min ph, v cch trang web ny h tr cc lp trnh vin  mi trnh . Ngoi ra, chng ta s cng tm hiu cch s dng nn tng ny hiu qu, l do v sao n c coi l mt "ngi bn ng hnh" khng th thiu.</p>
<h2 id="heading-free-fordev-la-gi">free-for.dev l g?</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1735464609127/078022f1-6394-4752-a2a6-9c02cd638416.png" alt="free-for-dev" class="image--center mx-auto" /></p>
<p><a target="_blank" href="https://free-for.dev/">free-for.dev</a> l mt danh sch tng hp cc cng c, dch v v ti nguyn min ph dnh ring cho lp trnh vin. Nn tng ny bt u t mt kho lu tr trn GitHub, v qua thi gian, n  tr thnh mt ngun ti nguyn ng tin cy v ph bin trong cng ng lp trnh.</p>
<p>Trang web cung cp hng trm cng c c phn loi r rng, bao gm cc dch v in ton m my, c s d liu, API th nghim, cng c CI/CD, v c cc cng c tng nng sut lm vic.</p>
<p>D bn l mt freelancer, startup ang tm kim gii php tit kim chi ph, hay mt sinh vin mun hc hi cng ngh mi, free-for.dev u c th p ng nhu cu ca bn.</p>
<h2 id="heading-cac-tinh-nang-noi-bat-cua-free-fordev">Cc tnh nng ni bt ca free-for.dev</h2>
<p>Vy iu g khin free-for.dev tr nn c bit? Hy cng khm ph nh!</p>
<h3 id="heading-1-phan-loai-tai-nguyen-ro-rang">1. <strong>Phn loi ti nguyn r rng</strong></h3>
<p>Trang web c t chc rt gn gng vi nhiu danh mc khc nhau, gip bn d dng tm kim cng c ph hp. Mt s danh mc ni bt bao gm:</p>
<ul>
<li><p><strong>Dch v m my:</strong> Cc nh cung cp dch v m my min ph nh AWS, Google Cloud, v Azure.</p>
</li>
<li><p><strong>API:</strong> Hng lot API min ph phc v cho th nghim, thu thp d liu, nh v a l, v nhiu hn na.</p>
</li>
<li><p><strong>C s d liu:</strong> Cc gii php SQL v NoSQL min ph nh MongoDB Atlas, Firebase, v PostgreSQL.</p>
</li>
<li><p><strong>Cng c pht trin:</strong> IDE, trnh son tho vn bn, v cng c g li.</p>
</li>
<li><p><strong>CI/CD:</strong> Cc cng c tch hp v trin khai lin tc nh GitHub Actions, Travis CI, v Jenkins.</p>
</li>
</ul>
<h3 id="heading-2-cap-nhat-thuong-xuyen">2. <strong>Cp nht thng xuyn</strong></h3>
<p>Nh vo s ng gp t cng ng, danh sch ti nguyn trn free-for.dev lin tc c lm mi, m bo rng bn lun c trong tay cc cng c mi nht.</p>
<h3 id="heading-3-mo-ta-chi-tiet">3. <strong>M t chi tit</strong></h3>
<p>Mi cng c u i km vi m t ngn gn, d hiu, gip bn nhanh chng nm c thng tin ct li v quyt nh xem n c ph hp vi nhu cu khng.</p>
<h3 id="heading-4-dua-tren-cong-dong-ma-nguon-mo">4. <strong>Da trn cng ng m ngun m</strong></h3>
<p>V free-for.dev l mt d n ngun m trn GitHub, bt k ai cng c th ng gp, cp nht, v thm ti nguyn mi. iu ny to ra mt mi trng lun pht trin v minh bch.</p>
<h2 id="heading-cach-su-dung-free-fordev-hieu-qua">Cch s dng free-for.dev hiu qu</h2>
<p><a target="_blank" href="https://free-for.dev/">free-for.dev</a> cc k d s dng. Di y l cc bc  tn dng ti a ti nguyn t trang web ny:</p>
<ol>
<li><p><strong>Khm ph danh mc:</strong> Hy bt u bng cch duyt qua cc danh mc  tm cng c ph hp cho d n ca bn.</p>
</li>
<li><p><strong>Tm kim nhanh:</strong> S dng thanh tm kim  tm cc dch v hoc cng c c th.</p>
</li>
<li><p><strong>c chi tit:</strong> Kim tra thng tin v gii hn v tnh nng ca phin bn min ph  hiu r nhng g bn s nhn c.</p>
</li>
<li><p><strong>ng gp:</strong> Nu bn bit cng c hay dch v min ph mi, hy ng gp cho cng ng thng qua kho GitHub ca free-for.dev.</p>
</li>
</ol>
<h2 id="heading-vi-sao-free-fordev-duoc-yeu-thich">V sao free-for.dev c yu thch?</h2>
<p>Di y l nhng l do khin nn tng ny tr thnh "tr th c lc" ca nhiu lp trnh vin:</p>
<ul>
<li><p><strong>Tit kim chi ph:</strong> Nhiu cng c trn free-for.dev cung cp cc tnh nng cao cp trong phin bn min ph, gip bn tit kim mt khon chi ph ng k.</p>
</li>
<li><p><strong>Tt c trong mt:</strong> y l ni tp trung tt c cc cng c m bn cn, gip bn tit kim thi gian tm kim.</p>
</li>
<li><p><strong>Cng ng h tr:</strong> Vic d n c cp nht lin tc bi cng ng gip n lun mi m v ng tin cy.</p>
</li>
<li><p><strong>Ph hp vi ngi mi:</strong> Cc lp trnh vin mi c th th nghim cc cng c cao cp m khng phi lo lng v chi ph.</p>
</li>
</ul>
<h2 id="heading-ket-luan">Kt lun</h2>
<p><a target="_blank" href="https://free-for.dev/">free-for.dev</a> thc s l mt ngun ti nguyn v gi dnh cho lp trnh vin. Vi hng trm cng c v dch v c phn loi r rng, nn tng ny s gip bn xy dng v trin khai d n mt cch hiu qu nht.</p>
<p>Bn cn chn ch g na? Hy bookmark v khm ph <a target="_blank" href="https://free-for.dev/">free-for.dev</a> ngay thi!</p>
]]></description><link>https://blog.thanhnamnguyen.dev/free-for-dev-tai-nguyen-mien-phi</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/free-for-dev-tai-nguyen-mien-phi</guid><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Giới thiệu về SEO và cấu hình SEO trong NextJS]]></title><description><![CDATA[<p>SEO l vit tt ca <strong>Search Engine Optimization</strong>, dch sang ting Vit l <strong>Ti u ha cng c tm kim</strong>. y l mt qu trnh k thut nhm gip website ca bn t c th hng cao hn trn trang kt qu ca cc cng c tm kim nh Google, Bing, Yahoo... khi ngi dng tm kim nhng t kha lin quan n sn phm, dch v hoc ni dung ca bn.</p>
<p><img src="https://d57439wlqx3vo.cloudfront.net/iblock/bc0/bc0f0fade6094e32d26afe9ee426bf47/a1d39b9944184055866844a5d88fdec3.png" alt="seo" /></p>
<p>Nhng SEO khng ch dng li  vic "ln top" - n cn gip tng tri nghim ngi dng, ci thin tc  ti trang, v gip website ca bn thu ht nhiu lu lng truy cp t nhin (organic traffic) hn.</p>
<p>Hin nay, vi hng triu website ang cnh tranh nhau trn Internet, SEO tr thnh mt phn khng th thiu trong chin lc pht trin website ca bt k doanh nghip hay c nhn no. Ni cch khc, nu khng c SEO, website ca bn d b "chm" trong bin thng tin khng l.</p>
<h2 id="heading-tai-sao-seo-lai-quan-trong"><strong>Ti sao SEO li quan trng?</strong></h2>
<ul>
<li><p><strong>Tng lng truy cp t nhin (Organic Traffic):</strong> SEO gip website ca bn xut hin trn cc trang kt qu tm kim (SERP). Khi ti u tt, website s thu ht khch truy cp t nhin m khng cn chi tin cho qung co qu nhiu.</p>
</li>
<li><p><strong>Nng cao uy tn:</strong> Khi website ca bn xut hin  v tr cao trn trang kt qu tm kim, ngi dng s nh gi cao hn v  tin cy v chuyn nghip ca bn.</p>
</li>
<li><p><strong>Tng t l chuyn i:</strong> Lng truy cp tng ng ngha vi vic bn c nhiu c hi chuyn i khch hng tim nng thnh khch hng thc t hn.</p>
</li>
<li><p><strong>Tit kim chi ph:</strong> So vi cc hnh thc qung co tr ph, SEO mang li hiu qu lu di v tit kim chi ph hn.</p>
</li>
<li><p><strong>Ci thin tri nghim ngi dng (User Experience - UX):</strong> Mt website thn thin vi SEO thng c tc  ti trang nhanh, thit k tng thch vi mi thit b v ni dung d c. iu ny khng ch lm hi lng Google m cn c ngi dng.</p>
</li>
<li><p><strong>Xy dng thng hiu (Brand Awareness):</strong> SEO gip bn xut hin trn top u tm kim, t  lm tng nhn din thng hiu v  tin cy ca khch hng i vi doanh nghip.</p>
</li>
<li><p><strong>Phn tch d liu v ti u lin tc:</strong> SEO khng phi l "mt ln v mi mi". N yu cu bn theo di cc ch s (nh traffic, thi gian trn trang, t l thot, v.v.)  khng ngng ci thin.</p>
</li>
</ul>
<h2 id="heading-seo-hoat-dong-nhu-the-nao"><strong>SEO hot ng nh th no?</strong></h2>
<p>Cc cng c tm kim s dng nhng thut ton phc tp  nh gi v xp hng cc website. SEO tp trung vo vic ti u ha cc yu t trn website ca bn  p ng c cc thut ton ny. Mt s yu t quan trng trong SEO bao gm:</p>
<ul>
<li><p><strong>Ni dung cht lng:</strong> Ni dung c o, hu ch v lin quan n t kha mc tiu s gip website ca bn hp dn c ngi dng v cc cng c tm kim.</p>
</li>
<li><p><strong>Cu trc website:</strong> Mt cu trc website r rng, d iu hng s gip cc cng c tm kim hiu r hn v ni dung ca bn.</p>
</li>
<li><p><strong>Ti u ha t kha:</strong> Vic s dng t kha mt cch hp l trong tiu , m t, ni dung v cc th meta s gip cng c tm kim hiu r hn v ch  ca trang.</p>
</li>
<li><p><strong>Lin kt:</strong> Cc lin kt n website ca bn t cc website khc (backlink) s gip tng uy tn v th hng ca website.</p>
</li>
<li><p><strong>Tc  ti trang:</strong> Mt website ti nhanh s mang li tri nghim tt hn cho ngi dng v c cc cng c tm kim nh gi cao.</p>
</li>
<li><p><strong>Tri nghim ngi dng:</strong> Thit k giao din thn thin, d s dng v ti u ha cho cc thit b di ng s gip ngi dng  li lu hn trn website ca bn.</p>
</li>
</ul>
<h2 id="heading-cac-loai-seo"><strong>Cc loi SEO</strong></h2>
<ul>
<li><p><strong>SEO On-page:</strong> Ti u ha cc yu t bn trong website nh ni dung, cu trc, th meta...</p>
</li>
<li><p><strong>SEO Off-page:</strong> Ti u ha cc yu t bn ngoi website nh xy dng backlink, qung b trn mng x hi...</p>
</li>
<li><p><strong>SEO k thut:</strong> Ti u ha cc yu t k thut ca website nh cu trc URL, cu trc file robots.txt, sitemap...</p>
</li>
</ul>
<h2 id="heading-cau-hinh-seo-trong-nextjs">Cu hnh SEO trong NextJS</h2>
<p>NextJS l mt framework React ni bt nh kh nng kt hp SSR (Server-Side Rendering) v SSG (Static Site Generation). iu ny lm cho Next.js tr thnh mt la chn l tng  ti u SEO. Di y l cch bn c th cu hnh SEO trong NextJS.</p>
<h3 id="heading-1-toi-uu-meta-tags">1. <strong>Ti u Meta tags</strong></h3>
<p>Meta tags nh <code>&lt;title&gt;</code>, <code>&lt;meta description&gt;</code> v cc th Open Graph l yu t ct li ca SEO. Trong NextJS, bn c th s dng <strong>next/head</strong>  thm cc th ny.</p>
<p><strong>V d:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-keyword">import</span> Head <span class="hljs-keyword">from</span> <span class="hljs-string">'next/head'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Home</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">title</span>&gt;</span>Gii thiu SEO trong Next.js<span class="hljs-tag">&lt;/<span class="hljs-name">title</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Hng dn ti u SEO vi framework Next.js."</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"keywords"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"SEO, Next.js, Ti u website, SSR, SSG"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:title"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Ti u ha SEO trong Next.js"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Cch s dng Next.js  tng th hng tm kim."</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:type"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"website"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Head</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Welcome to SEO with Next.js<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<h3 id="heading-2-su-dung-cac-chien-luoc-ssr-va-ssg">2. <strong>S dng cc chin lc SSR v SSG</strong></h3>
<ul>
<li><p><strong>SSR (Server-Side Rendering):</strong> Ni dung c render trn server v gi n trnh duyt. iu ny gip cc cng c tm kim d dng "c" ni dung ca bn.</p>
</li>
<li><p><strong>SSG (Static Site Generation):</strong> To cc trang tnh trc ti thi im build, l tng cho cc website c ni dung t thay i.</p>
</li>
</ul>
<p>V d khi s dng <strong>getStaticProps</strong> cho SSG:</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">getStaticProps</span>(<span class="hljs-params"></span>) </span>{
  <span class="hljs-keyword">const</span> data = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">'https://api.example.com/data'</span>);
  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">props</span>: {
      data,
    },
  };
}
</code></pre>
<h3 id="heading-3-them-sitemap-va-robotstxt">3. <strong>Thm Sitemap v Robots.txt</strong></h3>
<ul>
<li><p>Sitemap gip cc cng c tm kim hiu cu trc trang web. Bn c th s dng package <a target="_blank" href="https://www.npmjs.com/package/next-sitemap"><strong>next-sitemap</strong></a>  to t ng hoc <a target="_blank" href="https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap"><strong>to file sitemap.ts trong app</strong></a>.</p>
</li>
<li><p><a target="_blank" href="https://nextjs.org/docs/app/api-reference/file-conventions/metadata/robots"><strong>Robots.txt</strong></a> hng dn cng c tm kim nn (hoc khng nn) crawl nhng g.</p>
</li>
</ul>
<h3 id="heading-4-toi-uu-toc-do-tai-trang">4. <strong>Ti u tc  ti trang</strong></h3>
<ul>
<li><p><strong>Image Optimization:</strong> S dng <code>next/image</code>  gim kch thc nh.</p>
</li>
<li><p><strong>Lazy Loading:</strong> Ch ti nh khi chng hin th trn mn hnh.</p>
</li>
<li><p><strong>Code Splitting:</strong> Ch ti nhng phn cn thit ca m ngun.</p>
</li>
</ul>
<blockquote>
<p>Trong cc d n ln, vic cu hnh SEO mt cch th cng cho tng trang ring l c th rt tn thi gian. May mn thay, NextJS cung cp c ch <strong>Layout</strong> v <strong>generateMetadata</strong> (phin bn mi t NextJS 13) gip qun l SEO mt cch linh hot, c bit vi cc dynamic routes.</p>
</blockquote>
<h3 id="heading-5-cau-hinh-seo-voi-layout-trong-nextjs">5. <strong>Cu hnh SEO vi Layout trong NextJS</strong></h3>
<h4 id="heading-layout-la-gi"><strong>📌 Layout l g?</strong></h4>
<p>Trong NextJS, Layout l mt cch  chia s cu trc v logic chung cho nhiu trang trong ng dng ca bn. Vi SEO, Layout c th c dng  t cc th meta chung nh <code>&lt;title&gt;</code>, <code>&lt;meta description&gt;</code>, th Open Graph (OG), v nhiu hn na.</p>
<h4 id="heading-tao-layout-trong-nextjs"><strong>📌 To Layout trong NextJS</strong></h4>
<p>u tin, hy to mt file layout. Nu bn dng NextJS 13+ vi App Directory, file Layout c to  cp th mc, v d:</p>
<pre><code class="lang-javascript">/app
  /blog
    layout.js
    page.js
</code></pre>
<h4 id="heading-vi-du-cau-hinh-seo-trong-layoutjs"><strong>V d:</strong> Cu hnh SEO trong layout.js</h4>
<pre><code class="lang-javascript"><span class="hljs-comment">// app/blog/layout.js</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;
<span class="hljs-keyword">import</span> Head <span class="hljs-keyword">from</span> <span class="hljs-string">'next/head'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">const</span> metadata = {
  <span class="hljs-attr">title</span>: <span class="hljs-string">'Blog | Website ca bn'</span>,
  <span class="hljs-attr">description</span>: <span class="hljs-string">'Khm ph nhng bi vit mi nht v cng ngh, SEO, v pht trin web!'</span>,
  <span class="hljs-attr">keywords</span>: <span class="hljs-string">'SEO, Next.js, Blog, Cng ngh'</span>,
};

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">BlogLayout</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">Head</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"author"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"Your Name"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:type"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"website"</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:title"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">{metadata.title}</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">property</span>=<span class="hljs-string">"og:description"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">{metadata.description}</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"keywords"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">{metadata.keywords}</span> /&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">meta</span> <span class="hljs-attr">name</span>=<span class="hljs-string">"viewport"</span> <span class="hljs-attr">content</span>=<span class="hljs-string">"width=device-width, initial-scale=1.0"</span> /&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">Head</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>
        {children}
      <span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
    <span class="hljs-tag">&lt;/&gt;</span></span>
  );
}
</code></pre>
<p>Trong v d ny, Layout s t ng p dng cc th meta c cu hnh cho ton b cc trang nm trong th mc <code>/blog</code>.</p>
<h3 id="heading-6-cau-hinh-seo-cho-dynamic-routes-voi-generatemetadata">6. <strong>Cu hnh SEO cho Dynamic Routes vi generateMetadata</strong></h3>
<h4 id="heading-dynamic-routes-la-gi">📌 Dynamic Routes l g?</h4>
<p>Dynamic routes trong NextJS cho php bn to cc trang ng da trn tham s. V d: URL <code>/blog/[slug]</code> c th c s dng  hin th bi vit vi slug tng ng.</p>
<p>Khi kt hp vi <a target="_blank" href="https://nextjs.org/docs/app/api-reference/functions/generate-metadata"><strong>generateMetadata</strong></a> (mt tnh nng ca NextJS 13+), bn c th to metadata ng cho tng trang.</p>
<h4 id="heading-cach-su-dung-generatemetadata">📌 Cch s dng generateMetadata</h4>
<p><strong>Cu trc th mc:</strong></p>
<pre><code class="lang-bash">/app
  /blog
    /[slug]
      page.js
</code></pre>
<p><strong>To metadata ng da trn slug</strong></p>
<p>Trong <code>page.js</code>, bn c th truy vn d liu t API hoc c s d liu  to metadata ph hp cho mi bi vit.</p>
<pre><code class="lang-javascript"><span class="hljs-keyword">export</span> <span class="hljs-keyword">async</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">generateMetadata</span>(<span class="hljs-params">{ params, searchParams }, parent</span>) </span>{
  <span class="hljs-comment">// read route params</span>
  <span class="hljs-keyword">const</span> id = (<span class="hljs-keyword">await</span> params).id

  <span class="hljs-comment">// fetch data</span>
  <span class="hljs-keyword">const</span> product = <span class="hljs-keyword">await</span> fetch(<span class="hljs-string">`https://.../<span class="hljs-subst">${id}</span>`</span>).then(<span class="hljs-function">(<span class="hljs-params">res</span>) =&gt;</span> res.json())

  <span class="hljs-comment">// optionally access and extend (rather than replace) parent metadata</span>
  <span class="hljs-keyword">const</span> previousImages = (<span class="hljs-keyword">await</span> parent).openGraph?.images || []

  <span class="hljs-keyword">return</span> {
    <span class="hljs-attr">title</span>: product.title,
    <span class="hljs-attr">openGraph</span>: {
      <span class="hljs-attr">images</span>: [<span class="hljs-string">'/some-specific-page-image.jpg'</span>, ...previousImages],
    },
  }
}

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">Page</span>(<span class="hljs-params">{ params, searchParams }</span>) </span>{}
</code></pre>
<h3 id="heading-7-tich-hop-layout-va-generatemetadata">7. <strong>Tch hp Layout v generateMetadata</strong></h3>
<p>Bn c th kt hp c hai phng php trn  ti u ton b trang blog. Layout s qun l cc th meta chung, trong khi <strong>generateMetadata</strong> x l metadata ng cho tng bi vit.</p>
<p><strong>V d tch hp:</strong></p>
<pre><code class="lang-javascript"><span class="hljs-comment">// app/blog/[slug]/layout.js</span>
<span class="hljs-keyword">import</span> React <span class="hljs-keyword">from</span> <span class="hljs-string">'react'</span>;

<span class="hljs-keyword">export</span> <span class="hljs-keyword">default</span> <span class="hljs-function"><span class="hljs-keyword">function</span> <span class="hljs-title">PostLayout</span>(<span class="hljs-params">{ children }</span>) </span>{
  <span class="hljs-keyword">return</span> (
    <span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">header</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">h1</span>&gt;</span>Blog ca ti<span class="hljs-tag">&lt;/<span class="hljs-name">h1</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">header</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">main</span>&gt;</span>{children}<span class="hljs-tag">&lt;/<span class="hljs-name">main</span>&gt;</span>
      <span class="hljs-tag">&lt;<span class="hljs-name">footer</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>Bn quyn  2024<span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
      <span class="hljs-tag">&lt;/<span class="hljs-name">footer</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span>
  );
}
</code></pre>
<p>Hy vng bi vit ny cho bn hiu thm c v SEO v cu hnh chng trong NextJS.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/gioi-thieu-ve-seo-va-cau-hinh-seo-trong-nextjs</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/gioi-thieu-ve-seo-va-cau-hinh-seo-trong-nextjs</guid><category><![CDATA[SEO]]></category><category><![CDATA[Next.js]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Tìm hiểu về Headless CMS và CMS truyền thống]]></title><description><![CDATA[<p>H thng qun l ni dung (CMS) khng cn l khi nim xa l vi nhng ai lm vic trong lnh vc pht trin web. Vi s xut hin ca cng ngh mi, thut ng <strong>Headless CMS</strong> ngy cng ph bin hn, ha hn thay i cch chng ta qun l ni dung. Nhng bn  hiu r v CMS v s khc bit gia CMS truyn thng vi Headless CMS cha? Cng mnh khm ph ngay nh!</p>
<h2 id="heading-cms-la-gi">CMS l g?</h2>
<h3 id="heading-1-dinh-nghia-cms">1. nh ngha CMS</h3>
<p>CMS l vit tt ca <strong>Content Management System</strong>, tc H thng qun l ni dung. y l phn mm gip ngi dng d dng to, chnh sa, t chc, v qun l ni dung trn website m khng cn phi am hiu su v lp trnh. CMS nh mt "cng c tt c trong mt", gip mi ngi nhanh chng xy dng v vn hnh mt trang web hon chnh.</p>
<h3 id="heading-2-mot-so-vi-du-ve-cms">2. Mt s v d v CMS</h3>
<p>Mt s CMS quen thuc nht hin nay bao gm:</p>
<ul>
<li><p><strong>WordPress</strong> (chim hn 40% th phn website ton cu).</p>
</li>
<li><p><strong>Drupal</strong></p>
</li>
<li><p><strong>Joomla</strong></p>
</li>
<li><p><strong>Wix</strong></p>
</li>
<li><p><strong>Squarespace</strong></p>
</li>
<li><p>.</p>
</li>
</ul>
<p>Nhng nn tng ny thng c tch hp giao din ko th (drag-and-drop), gip ngi dng xy dng trang web d dng m khng cn k nng lp trnh chuyn su.</p>
<h2 id="heading-cms-truyen-thong-la-gi">CMS truyn thng l g?</h2>
<p>CMS truyn thng l m hnh CMS c s dng ph bin t nhiu nm nay, trong  <strong>backend</strong> (ni lu tr v qun l d liu) v <strong>frontend</strong> (giao din hin th vi ngi dng) c tch hp trong cng mt h thng. Ni cch khc, ni dung c qun l v trnh by trc tip trn mt nn tng duy nht.</p>
<p>Hy tng tng mt CMS truyn thng nh mt chic hp hon chnh: bn trong cha tt c cng c cn thit  to ra mt website hoc blog, t vic qun l ni dung, ci t giao din, n hin th trang cho ngi dng cui.</p>
<h2 id="heading-headless-cms-la-gi">Headless CMS l g?</h2>
<h3 id="heading-1-dinh-nghia-headless-cms">1. nh ngha Headless CMS</h3>
<p>Headless CMS l mt loi CMS khng bao gm "giao din hin th" (frontend) c nh. Thut ng "headless" ngha l n "khng u"  phn "u"  y m ch giao din ngi dng. Thay v kt ni trc tip ni dung vi giao din, Headless CMS ch tp trung vo vic qun l v cung cp ni dung thng qua API (Application Programming Interface).</p>
<p>Ni cch khc, Headless CMS ging nh mt "nh kho ni dung" m bn c th kt ni vi bt k nn tng no: website, ng dng di ng, thm ch l thit b IoT.</p>
<h3 id="heading-2-mot-so-vi-du-ve-headless-cms">2. Mt s v d v Headless CMS</h3>
<ul>
<li><p><strong>Contentful</strong></p>
</li>
<li><p><strong>Strapi</strong></p>
</li>
<li><p><strong>Sanity.io</strong></p>
</li>
<li><p><strong>Prismic</strong></p>
</li>
<li><p><strong>Ghost ( ch  Headless)</strong></p>
</li>
<li><p></p>
</li>
</ul>
<p>Nhng nn tng ny thng c a chung bi cc nh pht trin cn s linh hot trong cch s dng ni dung.</p>
<h2 id="heading-so-sanh-cms-truyen-thong-va-headless-cms">So snh CMS truyn thng v Headless CMS</h2>
<div class="hn-table">
<table>
<thead>
<tr>
<td><strong>Tiu ch</strong></td><td><strong>CMS truyn thng</strong></td><td><strong>Headless CMS</strong></td></tr>
</thead>
<tbody>
<tr>
<td><strong>Cu trc</strong></td><td>Tch hp c backend v frontend trong mt h thng duy nht.</td><td>Ch bao gm backend, frontend c tch ring v kt ni qua API.</td></tr>
<tr>
<td><strong>Tnh d s dng</strong></td><td>Thn thin vi ngi khng bit lp trnh, d thao tc v s dng giao din ko th.</td><td>i hi kin thc k thut, c bit trong vic kt ni API vi cc giao din frontend.</td></tr>
<tr>
<td><strong>Hiu sut</strong></td><td>Hiu sut c th b nh hng khi ni dung v plugin qu nhiu.</td><td>Hiu sut cao hn do backend c lp v frontend ti u ha.</td></tr>
<tr>
<td><strong>Tnh linh hot</strong></td><td>Hn ch trong vic ty chnh hoc trin khai ni dung trn nhiu nn tng khc nhau.</td><td>Rt linh hot, c th s dng ni dung trn mi knh (web, ng dng di ng, thit b IoT, v.v.).</td></tr>
<tr>
<td><strong>Quy trnh pht trin</strong></td><td>Nhanh chng, d dng trin khai website hoc blog trong thi gian ngn.</td><td>Yu cu thi gian v k thut  pht trin, c bit khi cn tch hp vi nhiu nn tng.</td></tr>
<tr>
<td><strong>Kh nng m rng</strong></td><td>Hn ch m rng khi d n pht trin ln hn hoc cn cng ngh hin i.</td><td>D dng m rng, ph hp vi cc d n c quy m ln v yu cu cng ngh cao.</td></tr>
<tr>
<td><strong>Tng thch SEO</strong></td><td>Tch hp sn cng c v plugin SEO, h tr ti u ha ni dung ngay trn nn tng.</td><td>Ph thuc vo vic tch hp th cng cc cng c SEO trong frontend.</td></tr>
<tr>
<td><strong>Chi ph</strong></td><td>Thng r hn hoc c bn min ph (nh WordPress).</td><td>Thng tn km hn do chi ph pht trin v bo tr cao hn.</td></tr>
<tr>
<td><strong>Kh nng tch hp cng ngh mi</strong></td><td>Hn ch tch hp vi cng ngh hin i (AI, IoT, chatbot, v.v.).</td><td>D dng tch hp vi cng ngh mi nh kt ni API linh hot.</td></tr>
<tr>
<td><strong>Trng hp s dng l tng</strong></td><td>Ph hp cho cc website c bn, blog c nhn, hoc cc d n nh, khng cn phc tp.</td><td>L tng cho cc ng dng a nn tng, website phc tp, hoc cc d n cn hiu sut cao.</td></tr>
</tbody>
</table>
</div><h2 id="heading-khi-nao-nen-chon-cms-truyen-thong-hoac-headless-cms">Khi no nn chn CMS truyn thng hoc Headless CMS?</h2>
<p><strong>Bn nn chn CMS truyn thng khi:</strong></p>
<ul>
<li><p>Bn cn xy dng nhanh mt website hoc blog c bn.</p>
</li>
<li><p>Bn khng c i ng lp trnh vin  pht trin.</p>
</li>
<li><p>Ngn sch d n hn ch.</p>
</li>
</ul>
<p><strong>Bn nn chn Headless CMS khi:</strong></p>
<ul>
<li><p>Bn cn trin khai ni dung trn nhiu nn tng (website, app, IoT).</p>
</li>
<li><p>Bn c i ng lp trnh vin  khi  vic ca bn ch l vit content cho web.</p>
</li>
<li><p>D n yu cu tnh nng phc tp hoc tch hp vi cng ngh hin i.</p>
</li>
</ul>
<h2 id="heading-mot-so-luu-y-khi-lua-chon-cms">Mt s lu  khi la chn CMS</h2>
<ul>
<li><p><strong>Xc nh nhu cu d n:</strong> Xem xt d n ca bn c yu cu phc tp khng.</p>
</li>
<li><p><strong>nh gi kh nng k thut:</strong> CMS truyn thng ph hp hn nu bn khng c i ng lp trnh.</p>
</li>
<li><p><strong>Ngn sch:</strong> Nu ngn sch hn ch, CMS truyn thng l la chn an ton hn.</p>
</li>
<li><p><strong>Kh nng m rng:</strong> Headless CMS s ph hp nu bn mun pht trin di hn vi kh nng m rng ln.</p>
</li>
</ul>
<h2 id="heading-ket-luan">Kt lun</h2>
<p>La chn gia CMS truyn thng v Headless CMS ph thuc rt nhiu vo mc tiu, yu cu v ngun lc ca bn. CMS truyn thng nh WordPress l la chn tuyt vi cho nhng ai mun n gin ha quy trnh, t mnh thc hin, trong khi Headless CMS li l gii php mnh m cho cc d n hin i, i hi s linh hot v hiu sut cao.</p>
<p>Hy vng bi vit  gip bn hiu r hn v hai loi CMS ph bin ny.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/tim-hieu-ve-headless-cms-va-cms-truyen-thong</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/tim-hieu-ve-headless-cms-va-cms-truyen-thong</guid><category><![CDATA[headless cms]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Docusaurus v3.6 có gì mới?]]></title><description><![CDATA[<p>Docusaurus l mt cng c c yu thch bi cc nh pht trin gip n gin ha vic to v qun l ti liu d n. Vi mi bn cp nht, i ng Docusaurus li mang n nhng tnh nng v ti u ha mi, gip ngi dng xy dng cc website ti liu cht lng cao, ty chnh linh hot v c hiu sut tt. Phin bn mi nht, Docusaurus v3.6 vi mt s tnh nng mi, ci tin, v sa li p ng nhu cu ca cng ng v nng cao tri nghim ngi dng.</p>
<p>Trong bi vit ny, chng ta s khm ph nhng im mi trong Docusaurus v3.6 nh!</p>
<p>Nu bn cha tng bit qua Docusarus, hy c bi vit ny <a target="_blank" href="https://blog.thanhnamnguyen.dev/tao-trang-web-voi-docusaurus">https://blog.thanhnamnguyen.dev/tao-trang-web-voi-docusaurus</a></p>
<h2 id="heading-diem-noi-bat">im ni bt</h2>
<p>Phin bn ny ch yu tp trung vo hiu sut xy dng thng qua d n <a target="_blank" href="https://github.com/facebook/docusaurus/issues/10556"><strong>Docusaurus Faster</strong></a>.</p>
<h3 id="heading-docusaurus-faster">Docusaurus Faster</h3>
<p>Mc tiu ca d n <a target="_blank" href="https://github.com/facebook/docusaurus/issues/10556"><strong>Docusaurus Faster</strong></a> l gim thi gian xy dng v tiu th b nh.</p>
<ul>
<li><p><a target="_blank" href="https://rspack.dev/"><strong>Rspack</strong></a>: Nhanh hn vi trnh ng gi web da trn Rust, thay th gn nh hon ho cho <a target="_blank" href="https://webpack.js.org/"><strong>webpack</strong></a><strong>.</strong></p>
</li>
<li><p><a target="_blank" href="https://swc.rs/"><strong>SWC</strong></a>: Trnh bin dch Web nhanh hn, nn tng da trn Rust cho Web (HTML, CSS, JS).</p>
</li>
<li><p><a target="_blank" href="https://lightningcss.dev/"><strong>Lightning CSS</strong></a>: Trnh phn tch c php CSS cc k nhanh, b chuyn i, ng gi v nn.</p>
</li>
</ul>
<h3 id="heading-giam-thoi-gian-build-web">Gim thi gian build web</h3>
<p><a target="_blank" href="https://github.com/facebook/docusaurus/issues/10556#issuecomment-2407671873">Cc php o th nghim</a> trn trang web cho thy bn c th build web nhanh hn t 2 n 4 ln.</p>
<h3 id="heading-tieu-thu-bo-nho">Tiu th b nh</h3>
<p>Bn cnh , Docusaurus Teams ci thin v vic tiu th b nh nh:</p>
<ul>
<li><p>C s h tng mi tiu th t b nh hn tng th.</p>
</li>
<li><p><a target="_blank" href="https://github.com/facebook/docusaurus/pull/10599">Sa mt li r r b nh</a> quan trng, c bit nh hng n cc trang web i18n.</p>
</li>
<li><p>Thm cc <a target="_blank" href="https://github.com/facebook/docusaurus/pull/10601">kim tra CI</a>.</p>
</li>
<li><p><a target="_blank" href="https://github.com/facebook/docusaurus/pull/10590">Thm cng c ni b</a>  hiu r hn bc no trong qu trnh xy dng tiu th b nh.</p>
</li>
<li><p><a target="_blank" href="https://github.com/facebook/docusaurus/pull/10410">Loi b mt lnh</a> <code>process.exit(0)</code> c th che giu cc li r r b nh trong m ca bn v cc plugin ca bn th ba.</p>
</li>
</ul>
<h3 id="heading-cac-tac-dong-khac">Cc tc ng khc</h3>
<ul>
<li><p>Trnh nn HTML hin s pht ra cnh bo trong <a target="_blank" href="https://github.com/facebook/docusaurus/discussions/10580">trng hp c nh du HTML khng hp l</a></p>
</li>
<li><p>Output HTML tnh <a target="_blank" href="https://github.com/facebook/docusaurus/pull/10554">gim hn ~5%</a>.</p>
</li>
<li><p>Mt s li c t ng sa bi c s h tng mi.</p>
</li>
</ul>
<h2 id="heading-huong-dan-cap-nhat-len-docusaurus-v36"><strong>Hng dn cp nht ln Docusaurus v3.6</strong></h2>
<p> cp nht ln phin bn mi nht, bn c th lm theo cc bc n gin sau y:</p>
<p><strong>Cp nht qua npm hoc yarn</strong></p>
<p>M terminal v chy lnh sau  cp nht:</p>
<pre><code class="lang-bash">npm install @docusaurus/core@latest @docusaurus/preset-classic@latest
</code></pre>
<p>Hoc:</p>
<pre><code class="lang-bash">yarn add @docusaurus/core@latest @docusaurus/preset-classic@latest
</code></pre>
<p>Thm package Docusaurus Faster vo d n:</p>
<pre><code class="lang-bash">npm install @docusaurus/faster
</code></pre>
<p>Sau khi ci, hy thm</p>
<pre><code class="lang-bash">  future: {
    experimental_faster: <span class="hljs-literal">true</span>,
  },
</code></pre>
<p>vo file <code>docusaurus.config.js</code>  chy vi Rspack thay v Webpack.</p>
<p>Trong trng hp mt trong cc c tnh nng khng hot ng cho trang web ca bn, bn c th bt cc c tnh nng mt cch c lp nh sau:</p>
<pre><code class="lang-javascript"> future: {
    <span class="hljs-attr">experimental_faster</span>: {
      <span class="hljs-attr">swcJsLoader</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">swcJsMinimizer</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">swcHtmlMinimizer</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">lightningCssMinimizer</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">rspackBundler</span>: <span class="hljs-literal">true</span>,
      <span class="hljs-attr">mdxCrossCompilerCache</span>: <span class="hljs-literal">true</span>,
    },
  },
</code></pre>
<ul>
<li><p><a target="_blank" href="https://github.com/facebook/docusaurus/pull/10435"><strong>swcJsLoader</strong></a>: S dng SWC  bin dch JS (thay v Babel)</p>
</li>
<li><p><a target="_blank" href="https://github.com/facebook/docusaurus/pull/10441"><strong>swcJsMinimizer</strong></a>: S dng SWC  nn JS (thay v Terser)</p>
</li>
<li><p><a target="_blank" href="https://github.com/facebook/docusaurus/pull/10554"><strong>swcHtmlMinimizer</strong></a>: S dng SWC  nn HTML v JS/CSS nhng (thay v html-minifier-terser)</p>
</li>
<li><p><a target="_blank" href="https://github.com/facebook/docusaurus/pull/10522"><strong>lightningCssMinimizer</strong></a>: S dng Lightning CSS  nn CSS (thay v cssnano v clean-css)</p>
</li>
<li><p><a target="_blank" href="https://github.com/facebook/docusaurus/pull/10402"><strong>rspackBundler</strong></a>: S dng Rspack  ng gi ng dng ca bn (thay v webpack)</p>
</li>
<li><p><a target="_blank" href="https://github.com/facebook/docusaurus/pull/10479"><strong>mdxCrossCompilerCache</strong></a>: Bin dch cc tp MDX mt ln cho c mi trng trnh duyt v Node.js thay v bin dch hai ln</p>
</li>
</ul>
<p>Sau khi thm vo file <code>docusaurus.config.js</code>. Bn hy chy d n ca bn v cm nhn, ng thi, kim tra li cc plugin v kim th sau khi cp nht  m bo rng khng c li hoc s c no pht sinh.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/docusaurus-v36-co-gi-moi</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/docusaurus-v36-co-gi-moi</guid><category><![CDATA[docusaurus]]></category><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Mẹo truy cập các trang web bị chặn mà không cần sử dụng VPN]]></title><description><![CDATA[<p>Bn mun truy cp mt trang web (chng hn nh Steam, Medium, Tawkto) nhng gp phi thng bo "trang web ny b chn"? ng lo, bn khng nht thit phi dng VPN  vt qua. Trong bi vit ny, chng ta s khm ph mo hu ch gip bn truy cp cc trang web b chn m khng cn dng n VPN.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728823691607/8dd2b9c9-07dd-42d2-b43d-fc88f54fd5b6.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-1-su-dung-proxy-web">1. S dng Proxy Web</h2>
<p>Mt trong nhng cch n gin nht  truy cp cc trang web b chn l s dng proxy web. Proxy hot ng nh mt trung gian, gip bn truy cp website qua mt my ch khc, t  n a ch IP ca bn. Proxy web thng d s dng, ch cn truy cp mt trang proxy, nhp URL ca trang web bn mun vo v bn c th truy cp ngay lp tc.</p>
<p><strong>Li ch ca Proxy:</strong></p>
<ul>
<li><p>D s dng, khng cn ci t.</p>
</li>
<li><p>C th truy cp ngay t trnh duyt.</p>
</li>
</ul>
<p><strong>Nhc im:</strong></p>
<ul>
<li><p>Tc  c th chm.</p>
</li>
<li><p>Khng an ton bng VPN, d liu c th khng c m ha.</p>
</li>
</ul>
<h2 id="heading-2-thay-doi-dns-ngay-tren-trinh-duyet">2. Thay i DNS ngay trn trnh duyt</h2>
<p>Domain Name System (DNS) l h thng phn gii tn min, v mt s trang web b chn bi cc nh cung cp dch v mng thng qua vic ngn chn DNS. Tuy nhin, bn c th d dng thay i DNS mc nh sang DNS cng cng, nh Google DNS hoc Cloudflare DNS,  vt qua vic ny.</p>
<h3 id="heading-21-tren-trinh-duyet-google-chrome">2.1. Trn trnh duyt Google Chrome</h3>
<p>Bn vo phn Settings  Privacy and security  Security.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728823614640/d242f7fc-7f33-44fe-9a19-645904237081.png" alt class="image--center mx-auto" /></p>
<p>Sau , cun trang xung di, tick chn s dng DNS v chn nh cung cp l Cloudflare (1.1.1.1)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728823641646/c790448a-c352-412a-8da7-4e7daaa74851.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-22-tren-trinh-duyet-microsoft-edge">2.2. Trn trnh duyt Microsoft Edge</h3>
<p>Bn vo phn Settings  Privacy, search, and services, sau  bn cun trang xung di, tick chn s dng DNS v chn nh cung cp l Cloudflare (1.1.1.1)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728823760638/08f408ac-a8f3-4ded-b375-1a088099e99e.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-23-tren-trinh-duyet-coc-coc">2.3. Trn trnh duyt Cc cc</h3>
<p>Bn vo phn Ci t  Quyn ring t v bo mt  Bo mt.</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728822910735/57cb26e6-1902-443a-a25b-5f6f6bae7036.png" alt class="image--center mx-auto" /></p>
<p>Sau , cun trang xung di, tick chn s dng DNS v chn nh cung cp l Cloudflare (1.1.1.1)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728822979711/114cb267-9e2f-4488-8060-308942801f7c.png" alt class="image--center mx-auto" /></p>
<h3 id="heading-24-tren-trinh-duyet-opera">2.4. Trn trnh duyt Opera</h3>
<p>Bn vo phn Settings  Privacy &amp; security  Security</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728823130273/d2b22e1c-d94c-41a7-a584-6d5a9290dfaf.png" alt class="image--center mx-auto" /></p>
<p>Sau , cun trang xung di, tick chn s dng DNS v chn nh cung cp l Cloudflare (1.1.1.1)</p>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728823222154/18553f3a-06e1-48f1-b7c1-c766eb490bea.png" alt class="image--center mx-auto" /></p>
<h2 id="heading-ket-qua">Kt qu</h2>
<p><img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1728823801952/8f335bb0-58d2-489d-a476-0d4a269bc4ce.png" alt class="image--center mx-auto" /></p>
<p>Hy vng mo nh ny gip bn lt web 1 cch d dng m khng cn s dng n VPN.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/meo-truy-cap-cac-trang-web-bi-chan-ma-khong-can-su-dung-vpn</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/meo-truy-cap-cac-trang-web-bi-chan-ma-khong-can-su-dung-vpn</guid><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item><item><title><![CDATA[Các thuật ngữ thiết kế hệ thống bạn cần biết]]></title><description><![CDATA[<p>Thit k h thng ng vai tr quan trng trong vic xy dng cc h thng phn mm c kh nng m rng v hiu qu, vic hiu r cc thut ng ny l iu cn thit. Hy cng mnh tm hiu 50 thut ng thit k h thng thng c s dng nh!</p>
<h3 id="heading-1-scalability-kha-nang-mo-rong">1. <strong>Scalability (Kh nng m rng)</strong></h3>
<p>Kh nng m rng  cp n vic h thng c th x l ti tng ln bng cch b sung ti nguyn (nh thm my ch). C hai loi chnh:</p>
<ul>
<li><p><strong>M rng ngang (Horizontal Scaling)</strong>: Thm nhiu my.</p>
</li>
<li><p><strong>M rng dc (Vertical Scaling)</strong>: Tng cng sc mnh ca my hin c.</p>
</li>
</ul>
<h3 id="heading-2-load-balancer-bo-can-bang-tai">2. <strong>Load Balancer (B cn bng ti)</strong></h3>
<p>B cn bng ti c trch nhim phn phi lu lng mng n nhiu my ch khc nhau  m bo khng c my ch no b qu ti.</p>
<h3 id="heading-3-caching-bo-nho-dem">3. <strong>Caching (B nh m)</strong></h3>
<p>B nh m lu tr bn sao d liu trong mt khu vc tm thi  cc yu cu sau c th c phc v nhanh hn.</p>
<h3 id="heading-4-latency-do-tre">4. <strong>Latency ( tr)</strong></h3>
<p> tr l thi gian  mt gi d liu di chuyn t ngun n ch. y l thc o quan trng  nh gi hiu sut ca h thng.</p>
<h3 id="heading-5-throughput-thong-luong">5. <strong>Throughput (Thng lng)</strong></h3>
<p>Thng lng l lng d liu m h thng c th x l trong mt khong thi gian nht nh, thng c o bng s yu cu trn giy (RPS).</p>
<h3 id="heading-6-high-availability-ha-kha-nang-san-sang-cao">6. <strong>High Availability (HA - Kh nng sn sng cao)</strong></h3>
<p>Kh nng sn sng cao  cp n h thng c thit k  hot ng lin tc m khng b gin on trong thi gian di, thng s dng cc chin lc d phng v chuyn i d phng.</p>
<h3 id="heading-7-fault-tolerance-kha-nang-chiu-loi">7. <strong>Fault Tolerance (Kh nng chu li)</strong></h3>
<p>Kh nng chu li l kh nng ca h thng tip tc hot ng bnh thng ngay c khi mt hoc nhiu thnh phn b li.</p>
<h3 id="heading-8-microservices-kien-truc-vi-dich-vu">8. <strong>Microservices (Kin trc vi dch v)</strong></h3>
<p>Microservices l mt phong cch kin trc trong  h thng c chia thnh cc dch v nh, c lp, giao tip vi nhau qua API.</p>
<h3 id="heading-9-monolithic-architecture-kien-truc-don-khoi">9. <strong>Monolithic Architecture (Kin trc n khi)</strong></h3>
<p>Tri ngc vi microservices, kin trc n khi kt hp tt c cc thnh phn ca mt ng dng thnh mt chng trnh lin kt cht ch.</p>
<h3 id="heading-10-api-gateway-cong-api">10. <strong>API Gateway (Cng API)</strong></h3>
<p>Cng API l im vo cho cc khch hng truy cp nhiu dch v vi m, gip n gin ha vic giao tip gia chng.</p>
<h3 id="heading-11-cap-theorem-dinh-ly-cap">11. <strong>CAP Theorem (nh l CAP)</strong></h3>
<p>nh l CAP cho rng mt h thng phn tn ch c th m bo hai trong ba thuc tnh:</p>
<ul>
<li><p>Tnh nht qun (Consistency)</p>
</li>
<li><p>Tnh sn sng (Availability)</p>
</li>
<li><p>Kh nng chu phn vng (Partition Tolerance).</p>
</li>
</ul>
<h3 id="heading-12-consistency-tinh-nhat-quan">12. <strong>Consistency (Tnh nht qun)</strong></h3>
<p>Tnh nht qun m bo rng mi yu cu c s nhn c d liu mi nht sau khi c mt yu cu ghi.</p>
<h3 id="heading-13-partition-tolerance-kha-nang-chiu-phan-vung">13. <strong>Partition Tolerance (Kh nng chu phn vng)</strong></h3>
<p>Kh nng chu phn vng  cp n kh nng ca h thng tip tc hot ng ngay c khi mt lin lc gia cc my ch.</p>
<h3 id="heading-14-eventual-consistency-nhat-quan-cuoi-cung">14. <strong>Eventual Consistency (Nht qun cui cng)</strong></h3>
<p>Trong cc h thng phn tn, nht qun cui cng c ngha l tt c cc bn sao ca d liu s tr nn nht qun sau mt khong thi gian, mc d khng ngay lp tc.</p>
<h3 id="heading-15-acid-properties-thuoc-tinh-acid">15. <strong>ACID Properties (Thuc tnh ACID)</strong></h3>
<p>ACID (Tnh nguyn t, Nht qun, C lp, Bn vng) l tp hp cc thuc tnh m bo cc giao dch trong c s d liu c x l mt cch ng tin cy.</p>
<h3 id="heading-16-base-model-mo-hinh-base">16. <strong>BASE Model (M hnh BASE)</strong></h3>
<p>BASE (Kh nng sn sng c bn, Trng thi mm, Nht qun cui cng) l mt s thay th cho ACID, thng c s dng trong cc c s d liu NoSQL.</p>
<h3 id="heading-17-load-shedding-giam-tai">17. <strong>Load Shedding (Gim ti)</strong></h3>
<p>Gim ti l mt c ch s dng  gim bt khi lng cng vic trn h thng bng cch loi b hoc u tin cc yu cu nht nh  duy tr s n nh.</p>
<h3 id="heading-18-data-replication-nhan-ban">18. <strong>Data Replication (Nhn bn)</strong></h3>
<p>Nhn bn l qu trnh sao chp d liu t mt v tr sang mt v tr khc  ci thin tnh sn sng v kh nng chu li.</p>
<h3 id="heading-19-database-sharding-phan-manh-co-so-du-lieu">19. <strong>Database Sharding (Phn mnh c s d liu)</strong></h3>
<p>Phn mnh c s d liu l qu trnh chia mt c s d liu ln thnh cc mnh nh hn, d qun l hn c gi l "shards".</p>
<h3 id="heading-20-nosql">20. <strong>NoSQL</strong></h3>
<p>NoSQL l loi c s d liu c thit k  x l khi lng ln d liu khng c cu trc, thng linh hot hn cc c s d liu quan h truyn thng.</p>
<h3 id="heading-21-sql-structured-query-language-ngon-ngu-truy-van-co-cau-truc">21. <strong>SQL (Structured Query Language - Ngn ng truy vn c cu trc)</strong></h3>
<p>SQL l ngn ng tiu chun dng  tng tc vi c s d liu quan h, chng hn nh truy vn v thay i d liu c cu trc.</p>
<h3 id="heading-22-master-slave-architecture-kien-truc-chu-to">22. <strong>Master-Slave Architecture (Kin trc Ch-T)</strong></h3>
<p>Trong m hnh ny, my ch ch x l tt c cc yu cu ghi, trong khi cc my ch t sao chp d liu t ch v phc v cc yu cu c.</p>
<h3 id="heading-23-leader-election-bau-chon-lanh-dao">23. <strong>Leader Election (Bu chn lnh o)</strong></h3>
<p>Bu chn lnh o l qu trnh trong cc h thng phn tn m cc nt ng  chn mt nt duy nht  ng vai tr lnh o cho vic iu phi.</p>
<h3 id="heading-24-heartbeats-nhip-dap">24. <strong>Heartbeats (Nhp p)</strong></h3>
<p>Nhp p l cc tn hiu nh k c gi gia cc nt  xc nhn rng chng vn hot ng v ang hot ng tt.</p>
<h3 id="heading-25-pubsub-publishsubscribe-dang-kyphat-hanh">25. <strong>Pub/Sub (Publish/Subscribe - ng k/Pht hnh)</strong></h3>
<p>Pub/Sub l m hnh nhn tin m ngi gi pht hnh cc thng bo m khng bit ngi nhn, v ngi nhn ng k nhn cc ch  thng bo c th.</p>
<h3 id="heading-26-message-queue-hang-doi-tin-nhan">26. <strong>Message Queue (Hng i tin nhn)</strong></h3>
<p>Hng i tin nhn l mt dng giao tip khng ng b, ni cc thng bo c lu tr trong hng i v x l theo th t vo trc ra trc (FIFO).</p>
<h3 id="heading-27-rate-limiting-gioi-han-tan-suat">27. <strong>Rate Limiting (Gii hn tn sut)</strong></h3>
<p>Gii hn tn sut kim sot s lng yu cu m mt khch hng c th gi n dch v, ngn nga lm dng v m bo tnh n nh.</p>
<h3 id="heading-28-circuit-breaker-pattern-mau-ngat-mach">28. <strong>Circuit Breaker Pattern (Mu ngt mch)</strong></h3>
<p>Mu ngt mch ngn chn h thng c gng thc hin mt hot ng c kh nng tht bi, cho php thi gian phc hi.</p>
<h3 id="heading-29-content-delivery-network-cdn-mang-phan-phoi-noi-dung">29. <strong>Content Delivery Network (CDN - Mng phn phi ni dung)</strong></h3>
<p>CDN l mt mng li cc my ch phn tn cung cp ni dung cho ngi dng da trn v tr a l ca h, gip ci thin thi gian ti.</p>
<h3 id="heading-30-ddos-distributed-denial-of-service-tan-cong-tu-choi-dich-vu-phan-tan">30. <strong>DDoS (Distributed Denial of Service - Tn cng t chi dch v phn tn)</strong></h3>
<p>DDoS l cuc tn cng khi nhiu h thng lm ngp bng thng hoc ti nguyn ca mt h thng mc tiu, lm cho n khng th phc v ngi dng.</p>
<h3 id="heading-31-throttling-dieu-chinh-toc-do">31. <strong>Throttling (iu chnh tc )</strong></h3>
<p>iu chnh tc  kim sot lu lng truy cp m h thng gi hoc nhn, ngn chn vic qu ti bng cch lm chm hoc t chi cc yu cu qu mc.</p>
<h3 id="heading-32-idempotency-tinh-dong-nhat">32. <strong>Idempotency (Tnh ng nht)</strong></h3>
<p>Tnh ng nht m bo rng vic thc hin cng mt thao tc nhiu ln s c hiu qu ging nh khi thc hin mt ln duy nht, thng rt quan trng trong cc API.</p>
<h3 id="heading-33-service-discovery-kham-pha-dich-vu">33. <strong>Service Discovery (Khm ph dch v)</strong></h3>
<p>Khm ph dch v cho php cc h thng t ng pht hin v tr ca cc dch v bn trong mng phn tn.</p>
<h3 id="heading-34-latency-vs-throughput-do-tre-va-thong-luong">34. <strong>Latency vs Throughput ( tr v Thng lng)</strong></h3>
<p> tr  cp n s chm tr trong vic x l mt yu cu n l, trong khi thng lng o lng c bao nhiu yu cu c th c x l trong mt khong thi gian nht nh.</p>
<h3 id="heading-35-sla-service-level-agreement-thoa-thuan-muc-dich-vu">35. <strong>SLA (Service Level Agreement - Tha thun mc dch v)</strong></h3>
<p>SLA l mt hp ng chnh thc gia nh cung cp dch v v khch hng, xc nh hiu sut v tnh sn sng mong i.</p>
<h3 id="heading-36-data-partitioning-phan-vung-du-lieu">36. <strong>Data Partitioning (Phn vng d liu)</strong></h3>
<p>Phn vng d liu l qu trnh chia mt tp d liu ln thnh cc phn nh hn  ci thin kh nng qun l v hiu sut.</p>
<h3 id="heading-37-quorum-quyen-bieu-quyet">37. <strong>Quorum (Quyn biu quyt)</strong></h3>
<p>Trong h thng phn tn, quorum l s lng ti thiu cc nt cn ng  cho mt quyt nh  n c chp nhn.</p>
<h3 id="heading-38-replication-lag-do-tre-sao-chep">38. <strong>Replication Lag ( tr sao chp)</strong></h3>
<p> tr sao chp xy ra khi c s chm tr gia vic ghi d liu vo my ch chnh v vic sao chp d liu  sang cc my ch ph.</p>
<h3 id="heading-39-data-consistency-models-cac-mo-hinh-nhat-quan-du-lieu">39. <strong>Data Consistency Models (Cc m hnh nht qun d liu)</strong></h3>
<p>Cc m hnh khc nhau (v d: Nht qun mnh, Nht qun cui cng) nh ngha cch d liu c truy cp v cp nht trong cc h thng phn tn.</p>
<h3 id="heading-40-strong-consistency-tinh-nhat-quan-manh">40. <strong>Strong Consistency (Tnh nht qun mnh)</strong></h3>
<p>Tnh nht qun mnh m bo rng sau khi thc hin thao tc ghi, bt k thao tc c no sau  u s tr v d liu  c cp nht.</p>
<h3 id="heading-41-consensus-algorithm-thuat-toan-dong-thuan">41. <strong>Consensus Algorithm (Thut ton ng thun)</strong></h3>
<p>Thut ton ng thun (v d: Paxos, Raft) c s dng  t c s ng thun v mt gi tr d liu duy nht gia cc h thng phn tn.</p>
<h3 id="heading-42-2pc-two-phase-commit-cam-ket-hai-giai-doan">42. <strong>2PC (Two-Phase Commit - Cam kt hai giai on)</strong></h3>
<p>2PC l mt thut ton phn tn m bo rng tt c cc bn tham gia vo mt giao dch hoc l s cam kt thay i ca h, hoc hy b n  duy tr tnh nht qun.</p>
<h3 id="heading-43-zookeeper">43. <strong>Zookeeper</strong></h3>
<p>Zookeeper l mt dch v iu phi phn tn dnh cho cc ng dng phn tn, cung cp cc chc nng nh bu chn lnh o v qun l cu hnh.</p>
<h3 id="heading-44-rate-limiting-algorithms-thuat-toan-gioi-han-tan-suat">44. <strong>Rate Limiting Algorithms (Thut ton gii hn tn sut)</strong></h3>
<p>Cc thut ton khc nhau (v d: Token Bucket, Leaky Bucket) c s dng  thc hin gii hn tn sut v qun l lu lng truy cp.</p>
<h3 id="heading-45-data-lake-ho-du-lieu">45. <strong>Data Lake (H d liu)</strong></h3>
<p>H d liu l mt kho lu tr tp trung lu tr lng ln d liu th  nh dng gc ca n cho n khi cn x l.</p>
<h3 id="heading-46-batch-processing-xu-ly-theo-lo">46. <strong>Batch Processing (X l theo l)</strong></h3>
<p>X l theo l lin quan n vic x l mt lng ln d liu cng mt lc, thng din ra sau mt khong thi gian nht nh, chng hn nh vo ban m.</p>
<h3 id="heading-47-stream-processing-xu-ly-dong-du-lieu">47. <strong>Stream Processing (X l dng d liu)</strong></h3>
<p>X l dng d liu cho php phn tch d liu lin tc, theo thi gian thc, ni d liu c x l ngay khi n n.</p>
<h3 id="heading-48-autoscaling-tu-dong-mo-rong">48. <strong>Autoscaling (T ng m rng)</strong></h3>
<p>T ng m rng iu chnh t ng s lng ti nguyn c phn b cho mt dch v da trn ti hin ti.</p>
<h3 id="heading-49-elasticity-tinh-dan-hoi">49. <strong>Elasticity (Tnh n hi)</strong></h3>
<p>Tnh n hi  cp n kh nng ca h thng m rng hoc thu hp da trn nhu cu.</p>
<h3 id="heading-50-containerization-dong-goi-container">50. <strong>Containerization (ng gi container)</strong></h3>
<p>ng gi container ng gi mt ng dng v cc phn ph thuc ca n vo mt container duy nht, cho php n chy n nh trn nhiu mi trng khc nhau (v d: Docker).</p>
<h3 id="heading-ket-luan">Kt lun</h3>
<p>Vic hiu r cc thut ng thit k h thng quan trng ny c th gip bn ci thin kh nng thit k v qun l cc h thng ln. Cho d bn ch mi bt u hay ang n tp li, vic nm vng nhng thut ng ny s gip bn lm vic hiu qu hn.</p>
]]></description><link>https://blog.thanhnamnguyen.dev/cac-thuat-ngu-thiet-ke-he-thong-ban-can-biet</link><guid isPermaLink="true">https://blog.thanhnamnguyen.dev/cac-thuat-ngu-thiet-ke-he-thong-ban-can-biet</guid><dc:creator><![CDATA[Thành Nam Nguyễn]]></dc:creator></item></channel></rss>