<?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: YAO ZELIANG</title>
    <description>The latest articles on DEV Community by YAO ZELIANG (@yaozeliang).</description>
    <link>https://dev.to/yaozeliang</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%2F735147%2Fbf2b3c74-8144-4b8c-94be-ec4e12cfdecc.jpeg</url>
      <title>DEV Community: YAO ZELIANG</title>
      <link>https://dev.to/yaozeliang</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/yaozeliang"/>
    <language>en</language>
    <item>
      <title>My first Web3 page with IPFS</title>
      <dc:creator>YAO ZELIANG</dc:creator>
      <pubDate>Sat, 26 Mar 2022 23:10:03 +0000</pubDate>
      <link>https://dev.to/yaozeliang/my-first-web3-page-with-ipfs-10o1</link>
      <guid>https://dev.to/yaozeliang/my-first-web3-page-with-ipfs-10o1</guid>
      <description>&lt;h2&gt;
  
  
  About
&lt;/h2&gt;

&lt;p&gt;As my first post in the community, I just want to record how I built and deployed my resume page on IPFS with &lt;a href="https://www.contentful.com/" rel="noopener noreferrer"&gt;Contentful&lt;/a&gt; and a classic template. Check out the final result :&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ENS domain (slow): &lt;a href="https://yaozeliang.eth.link" rel="noopener noreferrer"&gt;https://yaozeliang.eth.link&lt;/a&gt; &lt;/li&gt;
&lt;li&gt;DNS domain (fast): &lt;a href="https://zyao.on.fleek.co/" rel="noopener noreferrer"&gt;https://yaozeliang.github.io/me&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I still don't understand why it loads slowly with the ENS domain...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Some screenshots &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbu5d5ng732y5pvkryesv.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbu5d5ng732y5pvkryesv.png" alt=" " width="800" height="371"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fm0snx7ac85d84br406nx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fm0snx7ac85d84br406nx.png" alt=" " width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fzfzwsf75g9j20gun3gmd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fzfzwsf75g9j20gun3gmd.png" alt=" " width="800" height="381"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Basic structure
&lt;/h2&gt;

&lt;p&gt;Here is the basic structure for my site:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Domain: ENS Domain &lt;a href="https://ens.domains/" rel="noopener noreferrer"&gt;https://ens.domains/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Front-end: purchased template (jQuery,css,h5)&lt;/li&gt;
&lt;li&gt;Back-end: IPFS &lt;a href="https://ipfs.io/" rel="noopener noreferrer"&gt;https://ipfs.io/&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Code storage: Github&lt;/li&gt;
&lt;li&gt;Deploy: &lt;a href="https://fleek.co/" rel="noopener noreferrer"&gt;Fleek&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Form service: &lt;a href="https://formspree.io/" rel="noopener noreferrer"&gt;Formspree&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Comments plugin : &lt;a href="https://valine.js.org/en/quickstart.html" rel="noopener noreferrer"&gt;Valine.js&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Headless CMS: &lt;a href="https://www.contentful.com/" rel="noopener noreferrer"&gt;Conetentful&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Domain
&lt;/h3&gt;

&lt;p&gt;First, about my ENS domain, I have to admit I regret it immediately after purchasing one, it's costly and slow compared with a traditional DNS domain (at least for now), the only advantage from my perspective is that it can point to a cryptocurrency wallet, a content hash...&lt;/p&gt;

&lt;h3&gt;
  
  
  Front-end stuff
&lt;/h3&gt;

&lt;p&gt;As a python developer and free-lancer, I don't want to spend too much time struggling with any JS framework like react.js or vue.js, the main goal is to deliver a professional image to my client at first glance, so I purchased a template here : &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://themeforest.net/item/sunshine-a-vcard-template/19503929" rel="noopener noreferrer"&gt;Sunshine template&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Although it's published in 2017, I still like its design.&lt;/p&gt;

&lt;h3&gt;
  
  
  Back-end &amp;amp; Deploy
&lt;/h3&gt;

&lt;p&gt;I m interested in IPFS and still learning about it. for the conceptions and more details, you can find them on the official website: &lt;a href="https://ipfs.io/" rel="noopener noreferrer"&gt;https://ipfs.io/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;There are so many ways to use it, as a beginner I downloaded the desktop application and played around with the python HTTPS client module:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.ipfs.io/install/ipfs-desktop/#windows" rel="noopener noreferrer"&gt;Desktop windows version&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://pypi.org/project/ipfshttpclient/" rel="noopener noreferrer"&gt;python module ipfshttpclient&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;Desktop UI&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;it will execute the command like &lt;code&gt;ipfs init&lt;/code&gt; backend and generate an interface, if you are familiar with go, I think it's better to try the IPFS CLI tools directly&lt;br&gt;
&lt;a href="https://media2.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%2F3asyd8tfh8yg9jk2hvn3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F3asyd8tfh8yg9jk2hvn3.png" alt=" " width="800" height="406"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.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%2F4u92klevmo9dd5he1mvb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2F4u92klevmo9dd5he1mvb.png" alt=" " width="800" height="414"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Explore with python library&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Just a piece of advice, it's better to use the latest version for&lt;br&gt;
library ipfshttpclient, otherwise you may encounter some weird errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;pip&lt;/span&gt; &lt;span class="n"&gt;install&lt;/span&gt; &lt;span class="n"&gt;ipfshttpclient&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;a2&lt;/span&gt;
    &lt;span class="n"&gt;Found&lt;/span&gt; &lt;span class="n"&gt;existing&lt;/span&gt; &lt;span class="n"&gt;installation&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;ipfshttpclient&lt;/span&gt; &lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
    &lt;span class="n"&gt;Uninstalling&lt;/span&gt; &lt;span class="n"&gt;ipfshttpclient&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.6&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="n"&gt;Successfully&lt;/span&gt; &lt;span class="n"&gt;uninstalled&lt;/span&gt; &lt;span class="n"&gt;ipfshttpclient&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.6&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;Successfully&lt;/span&gt; &lt;span class="n"&gt;installed&lt;/span&gt; &lt;span class="n"&gt;ipfshttpclient&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mf"&gt;0.8&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="n"&gt;a2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As you can see here I tried version 0.6.0 the first time but it doesn't work, then we can try with the methods explained in the doc (create a client connection, upload files, pin with CID...)&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;import ipfshttpclient
# Default to local
client = ipfshttpclient.connect("/ip4/127.0.0.1/tcp/5001")
print(client)
&amp;lt;ipfshttpclient.client.Client object at 0x000001909A270910&amp;gt;
# upload a folder
client.add("test")
[&amp;lt;ipfshttpclient.client.base.ResponseBase: {'Name': 'resume-test/favicon.ico', 'Hash': 'QmXUrHJ3k5fZFUZhvGNzdqiPZgbnbr5LRN3VYDjwyqZmmf', 'Size': '15417'}&amp;gt;, &amp;lt;ipfshttpclient.client.base.ResponseBase: {'Name': 'resume-private-master/index.html', 'Hash': 'QmTiiC9BgBtpNuPG4QybLH9wMKZvgjp9wvTPqvA3R4439A', 'Size': '43377'}&amp;gt;]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The content we upload will be split by IPFS with a default chunker size of 256KB and each block has its unique hash (Content identifier CID) &lt;/p&gt;

&lt;p&gt;There are some important things to know, I recommend this article from DRIES BUYTAERT: &lt;a href="https://dri.es/my-first-web3-webpage" rel="noopener noreferrer"&gt;My first web3 webpage&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Headless CMS
&lt;/h3&gt;

&lt;p&gt;I use &lt;a href="https://www.contentful.com/" rel="noopener noreferrer"&gt;Conetentful&lt;/a&gt; to store my static sources like images, audios, videos...  With contentful, you can create a data model and retrieve them by API call.&lt;/p&gt;

&lt;p&gt;here's an example for collected books:&lt;br&gt;
&lt;a href="https://media2.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%2Fwkoq8fgmayg908chsds6.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fwkoq8fgmayg908chsds6.png" alt=" " width="800" height="442"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.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%2Fngndbniofiv7svm1crxu.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fngndbniofiv7svm1crxu.png" alt=" " width="800" height="379"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.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%2Fbh03wmmcfrndbcigv582.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fbh03wmmcfrndbcigv582.png" alt=" " width="800" height="459"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Third-party host service
&lt;/h3&gt;

&lt;p&gt;After modification for the template, I choose fleek to host my content on IPFS, it's pretty simple here, connect with GitHub and choose your repo, select a framework and add some commands if needed:&lt;br&gt;
&lt;a href="https://media2.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%2Fj62f16u588hx5kp55p11.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fj62f16u588hx5kp55p11.png" alt=" " width="800" height="360"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://media2.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%2Fmis3lcj69qsnldyeg5ks.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.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%2Fmis3lcj69qsnldyeg5ks.png" alt=" " width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click deploy and wait for a few seconds, I got the link and a CID for my site, the last thing to do is attach the site with my ENS domain. This can be done in the setting section.&lt;/p&gt;

&lt;h3&gt;
  
  
  Improvement
&lt;/h3&gt;

&lt;p&gt;Use a modern js framework, considering the frameworks supported by fleek, I personally recommend:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;React based: &lt;a href="https://www.gatsbyjs.com/" rel="noopener noreferrer"&gt;Gatsby&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Vue based: &lt;a href="https://gridsome.org/" rel="noopener noreferrer"&gt;Gridsome&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>web3</category>
      <category>ipfs</category>
      <category>javascript</category>
      <category>python</category>
    </item>
  </channel>
</rss>
