<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: kouveo</title>
    <description>The latest articles on DEV Community by kouveo (@sedangky).</description>
    <link>https://dev.to/sedangky</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F826632%2F2e97211b-a2d1-4596-a62d-2b5f94d8e5d3.png</url>
      <title>DEV Community: kouveo</title>
      <link>https://dev.to/sedangky</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sedangky"/>
    <language>en</language>
    <item>
      <title>vài lựa chọn xử lý rich text content từ graphcms với Nextjs site</title>
      <dc:creator>kouveo</dc:creator>
      <pubDate>Fri, 18 Mar 2022 06:50:32 +0000</pubDate>
      <link>https://dev.to/sedangky/vai-lua-chon-xu-ly-rich-text-content-tu-graphcms-voi-nextjs-site-56fm</link>
      <guid>https://dev.to/sedangky/vai-lua-chon-xu-ly-rich-text-content-tu-graphcms-voi-nextjs-site-56fm</guid>
      <description>&lt;p&gt;Cày Nextjs site, Kouveo thường xuyên gặp rắc rối. Vốn từ ngữ không đủ (cả tiếng Anh lẫn tiếng Việt) &lt;em&gt;nên đéo biết mô tả vande gặp fải thenao&lt;/em&gt;. Việc tìm jaifap rất chật vật và tốn thoijan. Thỉnh thoảng còn gặp trường hợp &lt;u&gt;đang tìm cách jaiquyet vande này&lt;/u&gt; thì jẫm mẹ fải &lt;u&gt;jaifap cho một vande khác&lt;/u&gt; trước đó.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgmjvrg3fzcj19afqdw6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fzgmjvrg3fzcj19afqdw6.png" alt="somewhere on reddit"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Hnay Kouveo bàn chuyện &lt;strong&gt;xử lý rich text content&lt;/strong&gt; từ GraphCMS trong Nextjs site.&lt;/p&gt;

&lt;h2&gt;
  
  
  GraphCMS data
&lt;/h2&gt;

&lt;p&gt;GraphCMS có mấy lựa chọn nhập data: &lt;strong&gt;Multiline Text&lt;/strong&gt;, &lt;strong&gt;Markdown&lt;/strong&gt; &amp;amp; &lt;strong&gt;Rich Text&lt;/strong&gt;. Kouveo thường zùng Rich Text mặc zù thích Markdown hơn. Có mấy lyzo:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jaozien nhập liệu Markdown của GraphCMS xấu ỉn, chữ rất bé, zùng lâu hại mắt.&lt;/li&gt;
&lt;li&gt;Kouveo chưa biết cách xử lý markdown với Nextjs.&lt;/li&gt;
&lt;li&gt;Nếu biết cách và cần zùng Markdown, vẫn lấy markdown data từ rich text được (qua truy vấn graphql).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Có một điểm khó chịu khi zùng Rich Text, đó là không zùng hình ảnh từ lienket ngoài (vizu Cloudinary, Imagekit...) được mà cứ fải upload lên assets folder của nó (GraphCMS).&lt;/p&gt;

&lt;p&gt;Truy vấn content data qua graphql, người zùng cothe lựa chọn ketqua trả về là &lt;strong&gt;text&lt;/strong&gt;, &lt;strong&gt;markdown&lt;/strong&gt;, &lt;strong&gt;html&lt;/strong&gt;, &lt;strong&gt;raw&lt;/strong&gt;. Đối với tay mơ như Kouveo, nhiều lựa chọn không fải tốt. Rất mất thoijan để tìm ra đúng cái mình cần và &lt;u&gt;fuongtien&lt;/u&gt; zùng để xử lý nó.&lt;/p&gt;

&lt;h2&gt;
  
  
  Vài fuongfap xử lý rich text content data (Nextjs)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Cách 1: Lấy ketqua html &amp;amp; zùng &lt;code&gt;dangerouslySetInnerHTML&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Cái này không cần cài đặt ji cả, cứ thế zùng luôn. Kouveo đặt className để làm style với các thành fần bên trong (nested elements?) bằng Tailwind.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; 
    &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"kouveo"&lt;/span&gt; 
    &lt;span class="na"&gt;dangerouslySetInnerHTML&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;__html&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
 &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cách 2: Lấy ketqua html &amp;amp; zùng &lt;code&gt;html-react-parser&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Zùng cách này nếu cần thay thế một số thanhfan noizung (cần &lt;a href="https://www.npmjs.com/package/html-react-parser" rel="noopener noreferrer"&gt;cài đặt trước&lt;/a&gt;). Vizu thay hình ảnh &lt;code&gt;&amp;lt;img ... &amp;gt; tag&lt;/code&gt; bằng &lt;code&gt;&amp;lt;Image ... &amp;gt; tag&lt;/code&gt; của Nextjs. &lt;/p&gt;

&lt;p&gt;Code zưới đây thay thế &lt;code&gt;&amp;lt;a&amp;gt; tags&lt;/code&gt; bằng &lt;code&gt;&amp;lt;Link&amp;gt; tags&lt;/code&gt; của ChakraUI&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// import&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;parse&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;html-react-parser&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// use&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Box&lt;/span&gt; &lt;span class="na"&gt;maxW&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"100%"&lt;/span&gt; &lt;span class="na"&gt;fontSize&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"xl"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;note&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;html&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domNode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="k"&gt;if &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;domNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attribs&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;domNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attribs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
                &lt;span class="k"&gt;return &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;
                        &lt;span class="na"&gt;href&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;domNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attribs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                        &lt;span class="na"&gt;color&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"teal.600"&lt;/span&gt;
                        &lt;span class="na"&gt;isExternal&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                        &lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;domNode&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;children&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Link&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;);&lt;/span&gt;
            &lt;span class="p"&gt;}&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nc"&gt;Box&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Cách 3: Lấy ketqua raw &amp;amp; zùng &lt;code&gt;@graphcms/rich-text-react-renderer&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Cách này cũng cần &lt;a href="https://www.npmjs.com/package/@graphcms/rich-text-react-renderer" rel="noopener noreferrer"&gt;cài đặt trước&lt;/a&gt;. Code zưới đây thay &lt;code&gt;&amp;lt;img ...&amp;gt; tag&lt;/code&gt; bằng &lt;code&gt;&amp;lt;Image ...&amp;gt; tag&lt;/code&gt; của Nextjs (Kouveo lược bớt một số chi tiết lằng nhằng).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// import&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;RichText&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@graphcms/rich-text-react-renderer&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;// use&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"kouveo"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;RichText&lt;/span&gt;
        &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;raw&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
        &lt;span class="na"&gt;renderers&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
            &lt;span class="na"&gt;img&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;altText&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;width&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nc"&gt;Image&lt;/span&gt;
                        &lt;span class="na"&gt;src&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;src&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                        &lt;span class="na"&gt;alt&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;altText&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                        &lt;span class="na"&gt;width&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;width&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                        &lt;span class="na"&gt;height&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;height&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
                        &lt;span class="na"&gt;layout&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"responsive"&lt;/span&gt;
                    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
                    &lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;figcaption&lt;/span&gt; &lt;span class="na"&gt;className&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;"text-sm italic"&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nx"&gt;altText&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;figcaption&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
                &lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;figure&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
            &lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="p"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;div&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Các fuongfap xử lý trên chưa chắc đã fải tốt nhất. Nhưng Kouveo mới chỉ biết đến thế. Cám ơn đã đọc.&lt;/p&gt;

</description>
      <category>nextjs</category>
      <category>graphcms</category>
      <category>richtext</category>
      <category>styles</category>
    </item>
  </channel>
</rss>
