<?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: Jeet Mandaliya</title>
    <description>The latest articles on DEV Community by Jeet Mandaliya (@sereneinserenade).</description>
    <link>https://dev.to/sereneinserenade</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%2F352374%2F56e33205-85d8-482c-8ac3-4d258ddbad66.png</url>
      <title>DEV Community: Jeet Mandaliya</title>
      <link>https://dev.to/sereneinserenade</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sereneinserenade"/>
    <language>en</language>
    <item>
      <title>How I implemented Google docs like commenting in Tiptap</title>
      <dc:creator>Jeet Mandaliya</dc:creator>
      <pubDate>Sun, 03 Apr 2022 10:53:46 +0000</pubDate>
      <link>https://dev.to/sereneinserenade/how-i-implemented-google-docs-like-commenting-in-tiptap-k2k</link>
      <guid>https://dev.to/sereneinserenade/how-i-implemented-google-docs-like-commenting-in-tiptap-k2k</guid>
      <description>&lt;p&gt;Tiptap has &lt;a href="https://github.com/ueberdosis/tiptap/issues/819" rel="noopener noreferrer"&gt;a GitHub issue&lt;/a&gt; with the list of all the community extensions in the repo where people share extensions that they create. &lt;a href="https://github.com/ueberdosis/tiptap/issues/819#issuecomment-875207116" rel="noopener noreferrer"&gt;Someone mentioned&lt;/a&gt; that they needed Commenting-feature in Tiptap that is similar to the commenting-feature in Google Docs. &lt;/p&gt;

&lt;p&gt;So here's how I had my chance of creating the same. &lt;/p&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&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%2Fassets%2Fgithub-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/sereneinserenade" rel="noopener noreferrer"&gt;
        sereneinserenade
      &lt;/a&gt; / &lt;a href="https://github.com/sereneinserenade/tiptap-comment-extension" rel="noopener noreferrer"&gt;
        tiptap-comment-extension
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Google-Docs 📄🔥 like commenting 💬 solution for Tiptap 2(https://tiptap.dev)
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Tiptap Comment Extension:&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;
  &lt;a rel="noopener noreferrer" href="https://github.com/sereneinserenade/tiptap-comment-extensionassets/logo.svg"&gt;&lt;img src="https://media.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgithub.com%2Fsereneinserenade%2Ftiptap-comment-extensionassets%2Flogo.svg" width="200"&gt;&lt;/a&gt;
&lt;/p&gt;

&lt;p&gt;&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/a5702c5c62a4e8cb47668be5246794f4da82029516d4cd55f1d46c0a1efc0675/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73706f6e736f72732f736572656e65696e736572656e6164653f636f6c6f723d253233626633393839266c6162656c3d53706f6e736f722532304d65267374796c653d666f722d7468652d6261646765"&gt;&lt;img src="https://camo.githubusercontent.com/a5702c5c62a4e8cb47668be5246794f4da82029516d4cd55f1d46c0a1efc0675/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73706f6e736f72732f736572656e65696e736572656e6164653f636f6c6f723d253233626633393839266c6162656c3d53706f6e736f722532304d65267374796c653d666f722d7468652d6261646765" alt="GitHub Sponsors"&gt;&lt;/a&gt;
&lt;a rel="noopener noreferrer nofollow" href="https://camo.githubusercontent.com/1fd88e1bca98fcba13ad1e6ad1e69b8f5ab7a62394428abcf94b705234a245d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f736572656e65696e736572656e6164652f7469707461702d636f6d6d656e742d657874656e73696f6e3f6c6162656c3d537461722532307468652532305265706f267374796c653d666f722d7468652d6261646765"&gt;&lt;img src="https://camo.githubusercontent.com/1fd88e1bca98fcba13ad1e6ad1e69b8f5ab7a62394428abcf94b705234a245d7/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f736572656e65696e736572656e6164652f7469707461702d636f6d6d656e742d657874656e73696f6e3f6c6162656c3d537461722532307468652532305265706f267374796c653d666f722d7468652d6261646765" alt="GitHub Repo stars"&gt;&lt;/a&gt;
DM Me on Discord - sereneinserenade#4869&lt;/p&gt;
&lt;p&gt;&lt;a href="https://tiptap.dev/guide/custom-extensions" rel="nofollow noopener noreferrer"&gt;Tiptap Extension&lt;/a&gt; for having Google-Docs like pro-commenting in Tiptap.&lt;/p&gt;
&lt;p&gt;A ⭐️ to the repo if you 👍 / ❤️ what I'm doing would be much appreciated. If you're using this extension and making money from it, it'd be very kind of you to &lt;strong&gt;&lt;a href="https://github.com/sponsors/sereneinserenade" rel="noopener noreferrer"&gt;❤️ Sponsor me&lt;/a&gt;&lt;/strong&gt;. If you're looking for a &lt;strong&gt;dev to work you on your project's Rich Text Editor&lt;/strong&gt; with or as &lt;strong&gt;a frontend developer&lt;/strong&gt;, &lt;a href="https://github.com/sereneinserenade" rel="noopener noreferrer"&gt;DM me on Discord/Twitter/LinkedIn&lt;/a&gt;👨‍💻🤩.&lt;/p&gt;
&lt;p&gt;I've made a bunch of extensions for Tiptap 2, some of them are &lt;strong&gt;Resiable Images And Videos&lt;/strong&gt;, &lt;strong&gt;Search and Replace&lt;/strong&gt;, &lt;strong&gt;LanguageTool integration&lt;/strong&gt; with tiptap. You can check it our here &lt;a href="https://github.com/sereneinserenade#a-glance-of-my-projects" rel="noopener noreferrer"&gt;https://github.com/sereneinserenade#a-glance-of-my-projects&lt;/a&gt;.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Demo:&lt;/h2&gt;
&lt;/div&gt;
&lt;p&gt;Try live demo: &lt;a href="https://sereneinserenade.github.io/tiptap-comment-extension/" rel="nofollow noopener noreferrer"&gt;https://sereneinserenade.github.io/tiptap-comment-extension/&lt;/a&gt;&lt;/p&gt;

  
    
    

    &lt;span class="m-1"&gt;tiptap-comment-extension.mp4&lt;/span&gt;
    
  

  

  


&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;How to use&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;npm i &lt;a class="mentioned-user" href="https://dev.to/sereneinserenade"&gt;@sereneinserenade&lt;/a&gt;/tiptap-comment-extension&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="highlight highlight-source-ts notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-smi"&gt;StarterKit&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;"@tiptap/starter-kit"&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-k"&gt;import&lt;/span&gt; &lt;span class="pl-smi"&gt;CommentExtension&lt;/span&gt; &lt;span class="pl-k"&gt;from&lt;/span&gt; &lt;span class="pl-s"&gt;"&lt;a class="mentioned-user" href="https://dev.to/sereneinserenade"&gt;@sereneinserenade&lt;/a&gt;/tiptap-comment-extension"&lt;/span&gt;&lt;span class="pl-kos"&gt;;&lt;/span&gt;
&lt;span class="pl-c"&gt;/* or&lt;/span&gt;
&lt;span class="pl-c"&gt;import { CommentExtension } from "&lt;a class="mentioned-user" href="https://dev.to/sereneinserenade"&gt;@sereneinserenade&lt;/a&gt;/tiptap-comment-extension";&lt;/span&gt;
&lt;span class="pl-c"&gt;*/&lt;/span&gt;

&lt;span class="pl-k"&gt;const&lt;/span&gt; &lt;span class="pl-s1"&gt;extensions&lt;/span&gt;&lt;/pre&gt;…
&lt;/div&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/sereneinserenade/tiptap-comment-extension" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


&lt;p&gt;Initially I created it just for Vue3 since it's only supposed to be an example implementation of a framework agnostic Tiptap extension. And by the &lt;a href="https://github.com/sereneinserenade/tiptap-comment-extension/issues/2" rel="noopener noreferrer"&gt;request of community&lt;/a&gt; there's also an &lt;a href="https://github.com/sereneinserenade/tiptap-comment-extension-react" rel="noopener noreferrer"&gt;implementation in React&lt;/a&gt;. If you want to check it out before we jump into the code, here's &lt;a href="https://tiptap-comment-extension.vercel.app/" rel="noopener noreferrer"&gt;a demo.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Okay, enough context, let's dive into how it's made.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;When I started working on it, the first thing I did was to Google whether there were any discussions around it, and I found &lt;a href="https://discuss.prosemirror.net/t/inlining-a-node-for-a-comment-plugin-or-best-to-use-marks/2391" rel="noopener noreferrer"&gt;this thread&lt;/a&gt;, which at the time I couldn't comprehend fully because of my limited knowledge of Prosemirror. I got to know pros and cons of implementing comments as marks and the other solution, which mentioned storing ranges of comments in an external data structure, and highlighting the comments in the doc with Prosemirror decorations, but then we'd have to figure out how to transfer comments when copying the content from one doc and pasting to another doc.&lt;/p&gt;

&lt;p&gt;After all, I decided to give a shot to Comments as marks since I was already familiar with marks. So I created a new Mark, here's &lt;a href="https://github.com/sereneinserenade/tiptap-comment-extension/blob/main/src/components/extension/comment.ts" rel="noopener noreferrer"&gt;the file&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CommentOptions&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;HTMLAttributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;Record&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;string&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kr"&gt;any&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;}&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Comment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Mark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CommentOptions&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="nf"&gt;addOptions&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="na"&gt;HTMLAttributes&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="nf"&gt;parseHTML&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;{&lt;/span&gt;
        &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&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="nf"&gt;renderHTML&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;HTMLAttributes&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nf"&gt;mergeAttributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;HTMLAttributes&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;HTMLAttributes&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="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Right now, we have created a comment mark, that'll just render a span, but we need to store the comments somewhere. That's when the &lt;code&gt;data-comment&lt;/code&gt; attribute comes in.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Comment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;Mark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;create&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CommentOptions&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="c1"&gt;// ... rest of code&lt;/span&gt;
  &lt;span class="nf"&gt;addAttributes&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="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;default&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;parseHTML&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&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="nx"&gt;el&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLSpanElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
        &lt;span class="na"&gt;renderHTML&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;attrs&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="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comment&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="nf"&gt;parseHTML&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;{&lt;/span&gt;
        &lt;span class="na"&gt;tag&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;span[data-comment]&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;getAttrs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;el&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;HTMLSpanElement&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;getAttribute&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;data-comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)?.&lt;/span&gt;&lt;span class="nf"&gt;trim&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="kc"&gt;null&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="c1"&gt;// ... rest of code&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Now, it would render a &lt;code&gt;data-comment&lt;/code&gt; attribute with span element, and adding a Tiptap-Attribute will allow us to define the &lt;code&gt;comment&lt;/code&gt; property of mark so we can access it programmatically instead of getting &lt;code&gt;data-comment&lt;/code&gt; attribute by searching through DOM.&lt;/p&gt;

&lt;p&gt;We need commands to be able to set comment mark.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="c1"&gt;// ... rest of code&lt;/span&gt;
  &lt;span class="nf"&gt;addCommands&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="na"&gt;setComment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="na"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;string&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="nx"&gt;commands&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;setMark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="p"&gt;}),&lt;/span&gt;
      &lt;span class="na"&gt;toggleComment&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;commands&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;toggleMark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="na"&gt;unsetComment&lt;/span&gt;&lt;span class="p"&gt;:&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="nx"&gt;commands&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;commands&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;unsetMark&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment&lt;/span&gt;&lt;span class="dl"&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="c1"&gt;// ... rest of code&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;That's it for the extension part. Now we look at how we're going to structure the comments and store them, which leads us to the Vue part of things, which is implemented &lt;a href="https://github.com/sereneinserenade/tiptap-comment-extension/blob/main/src/components/Tiptap.vue" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="kr"&gt;interface&lt;/span&gt; &lt;span class="nx"&gt;CommentInstance&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nl"&gt;uuid&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;string&lt;/span&gt;
  &lt;span class="nx"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;?:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// to store currently active instance&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;activeCommentsInstance&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;CommentInstance&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&lt;span class="p"&gt;({})&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;allComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;ref&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kr"&gt;any&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="c1"&gt;// to store all comments&lt;/span&gt;


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

&lt;/div&gt;

&lt;p&gt;Loading all the comments when editor is created and updated, setting currently active comment when editor is updated.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;findCommentsAndStoreValues&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Editor&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="kd"&gt;const&lt;/span&gt; &lt;span class="na"&gt;tempComments&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kr"&gt;any&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;

  &lt;span class="c1"&gt;// to get the comments from comment mark.&lt;/span&gt;
  &lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;descendants&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;pos&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="kd"&gt;const&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;marks&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;

    &lt;span class="nx"&gt;marks&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;mark&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;mark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="kd"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;markComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;mark&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;attrs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// accessing the comment attribute programmatically as mentioned before&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;jsonComments&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;markComments&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&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;markComments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;null&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;jsonComments&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nx"&gt;tempComments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="nx"&gt;jsonComments&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pos&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;pos&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;text&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="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;

  &lt;span class="nx"&gt;allComments&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;tempComments&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;setCurrentComment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;Editor&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;newVal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;isActive&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment&lt;/span&gt;&lt;span class="dl"&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;newVal&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setTimeout&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="nx"&gt;showCommentMenu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;newVal&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;showAddCommentSection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;empty&lt;/span&gt;

    &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;parsedComment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&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;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;getAttributes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;comment&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;parsedComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comment&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;typeof&lt;/span&gt; &lt;span class="nx"&gt;parsedComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comments&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;JSON&lt;/span&gt;&lt;span class="p"&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;parsedComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comments&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;parsedComment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;comments&lt;/span&gt;

    &lt;span class="nx"&gt;activeCommentsInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;parsedComment&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;activeCommentsInstance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&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="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;tiptapEditor&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;useEditor&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
    &amp;lt;p&amp;gt; Comment here. &amp;lt;/p&amp;gt;
  `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;

  &lt;span class="na"&gt;extensions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;StarterKit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;Comment&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="nf"&gt;onUpdate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;findCommentsAndStoreValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nf"&gt;setCurrentComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="nf"&gt;onSelectionUpdate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;setCurrentComment&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

    &lt;span class="nx"&gt;isTextSelected&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;!!&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;state&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;selection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;content&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;size&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="nf"&gt;onCreate&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;editor&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nf"&gt;findCommentsAndStoreValues&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;editor&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;

  &lt;span class="na"&gt;editorProps&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;attributes&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;spellcheck&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;false&lt;/span&gt;&lt;span class="dl"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;That was the core logic of how to get comments from Tiptap and store then in Vue so it can be use outside of the scope of editor. &lt;/p&gt;

&lt;p&gt;Here's the structure of the comments that made most sense to me. However, since it's just going to be a string in the &lt;code&gt;data-comment&lt;/code&gt; property, you can have any JSON or XML or YAML or whatever format you want, just make sure you parse it right.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight typescript"&gt;&lt;code&gt;

&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;uuid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;d1858137-e0d8-48ac-9f38-ae778b56c719&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;comments&lt;/span&gt;&lt;span class="dl"&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="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sereneinserenade&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1648338852939&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;First comment&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;userName&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;sereneinserenade&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;time&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1648338857073&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;content&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;Following Comment&lt;/span&gt;&lt;span class="dl"&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;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;p&gt;The other part of logic(which I consider to be not-core logic) , i.e. creating a new comment, toggling comment mode on/off and showing &lt;a href="https://github.com/sereneinserenade/tiptap-comment-extension/blob/main/src/components/OuterComment.vue" rel="noopener noreferrer"&gt;the comments outside&lt;/a&gt; can be found in the repo.&lt;/p&gt;

&lt;p&gt;Enjoy the days, and if you have any questions/suggestions, I'll be in the comment section.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Next-Gen Text Editing in Browser With Tiptap 🔥</title>
      <dc:creator>Jeet Mandaliya</dc:creator>
      <pubDate>Sun, 31 Jan 2021 23:06:33 +0000</pubDate>
      <link>https://dev.to/sereneinserenade/next-gen-text-editing-in-browser-with-tiptap-2943</link>
      <guid>https://dev.to/sereneinserenade/next-gen-text-editing-in-browser-with-tiptap-2943</guid>
      <description>&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%2Fwebdevjeet.me%2Fcontent%2Fimages%2F2021%2F01%2Ftitle-image-3.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%2Fwebdevjeet.me%2Fcontent%2Fimages%2F2021%2F01%2Ftitle-image-3.png" alt="Next-Gen Text Editing in Browser With Tiptap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Good day folks, I've decided to write a series about one of the Web-World's most underrated topics, which is web-based rich text editors. In this series, I'll be first covering &lt;a href="https://tiptap.dev/" rel="noopener noreferrer"&gt;Tiptap&lt;/a&gt; and describe how we can build great web-based text editors using tiptap.&lt;/p&gt;




&lt;h3&gt;
  
  
  Requirements:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;A little bit of familiarity with JavaScript and VueJS.&lt;/li&gt;
&lt;li&gt;A VueJS project ( existing or new ).&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Tiptap is a renderless rich-text editor made originally for VueJS. Tiptap uses &lt;a href="https://prosemirror.net/" rel="noopener noreferrer"&gt;Prosemirror&lt;/a&gt; under the hood which is a toolkit that provides various abstractions to manipulate DOM and transform its content to specific formatting we want. In other words, it can transform a normal text into a bold text(and much more) and vice-versa very easily.&lt;/p&gt;

&lt;p&gt;Another very powerful aspect of Tiptap is that it fills the gap between writing markdown and rich text. For example, if you want to use a heading and write a &lt;strong&gt;'#'&lt;/strong&gt; at the start of a line and press space, it'll turn that line into an H1 for instance.&lt;/p&gt;

&lt;p&gt;Okay enough intro, let's take a look at the official example and let's figure out more about it on the journey. You can take a look at many more examples with customizations at &lt;a href="https://tiptap.dev/" rel="noopener noreferrer"&gt;tiptap.dev&lt;/a&gt;.&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%2Fwebdevjeet.me%2Fcontent%2Fimages%2F2021%2F01%2Fimage.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%2Fwebdevjeet.me%2Fcontent%2Fimages%2F2021%2F01%2Fimage.png" alt="Next-Gen Text Editing in Browser With Tiptap"&gt;&lt;/a&gt;Isn't it enchanting ?&lt;/p&gt;

&lt;h3&gt;
  
  
  Installation
&lt;/h3&gt;

&lt;p&gt;Tiptap can be installed with help of NPM of Yarn. NPM ships with NodeJS. Here are instructions for installing &lt;a href="https://nodejs.org/en/" rel="noopener noreferrer"&gt;NPM&lt;/a&gt; and &lt;a href="https://yarnpkg.com/getting-started/install" rel="noopener noreferrer"&gt;Yarn&lt;/a&gt;.&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm install --save tiptap


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

&lt;/div&gt;
&lt;p&gt;&lt;em&gt;or&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

yarn add tiptap


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

&lt;/div&gt;
&lt;p&gt;Once we have tiptap installed, we can directly start using it, or we can install extensions first. The power of Tiptap(or so to say Prosemirror) lies in the extensions. Any functionality you'd like to have can be written as an extension and plugged into Tiptap's running instance and we'd have an editor with our custom functionality.&lt;/p&gt;

&lt;p&gt;Tiptap team has a nice set of extensions in NPM package &lt;code&gt;tiptap-extensions&lt;/code&gt; and they maintain them which makes them guaranteed to work with Tiptap. Some of them are Blockquote, CodeBlock, HardBreak, Heading, OrderedList, BulletList, ListItem, TodoItem, TodoList, Bold, Code, Italic, Link, Strike, Underline, History.&lt;/p&gt;

&lt;p&gt;Each of them is required for adding specific behaviour to our editor. It can be installed with the following method.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm install --save tiptap-extensions


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

&lt;/div&gt;
&lt;p&gt;&lt;em&gt;or&lt;/em&gt;&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

yarn add tiptap-extensions



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

&lt;/div&gt;
&lt;h3&gt;
  
  
  Initializing
&lt;/h3&gt;

&lt;p&gt;For the scope of this post, we're just going to use basic extensions like Bold, Italic, Underline, Headings. Now, since everyone has a past, we're including the History extension too. In your project, you can create a new specific folder to keep all the JS files and VueJS components written for the Editor. In my case, I've created a bare VueJS 2 project with Babel and ESLint and have created a dir named &lt;code&gt;editor&lt;/code&gt; in my &lt;code&gt;src&lt;/code&gt; folder like this.&lt;/p&gt;

&lt;p&gt;Instructions to initialize a new VueJS project &lt;a href="https://cli.vuejs.org/guide/creating-a-project.html" rel="noopener noreferrer"&gt;can be found here&lt;/a&gt;.&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%2Fwebdevjeet.me%2Fcontent%2Fimages%2F2021%2F01%2Fimage-1.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%2Fwebdevjeet.me%2Fcontent%2Fimages%2F2021%2F01%2Fimage-1.png" alt="Next-Gen Text Editing in Browser With Tiptap"&gt;&lt;/a&gt;Created A New Vue Project&lt;/p&gt;

&lt;p&gt;Then I'll be installing &lt;code&gt;tiptap&lt;/code&gt; and &lt;code&gt;tiptap-extensions&lt;/code&gt;. Here, I'm installing two packages with NPM in one shot. We can separate them with a space in between and NPM will do the rest for us.&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;

npm install --save tiptap tiptap-extensions


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

&lt;/div&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%2Fwebdevjeet.me%2Fcontent%2Fimages%2F2021%2F01%2Fimage-2.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%2Fwebdevjeet.me%2Fcontent%2Fimages%2F2021%2F01%2Fimage-2.png" alt="Next-Gen Text Editing in Browser With Tiptap"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once installed, we can move on to our &lt;strong&gt;tiptap.js&lt;/strong&gt; file showed in the screenshot above and start working with Tiptap.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In this file, we're initializing an instance of Tiptap Editor with the extensions we want to use. Now it's time to use this in &lt;strong&gt;Tiptap.vue&lt;/strong&gt;. Here's what &lt;strong&gt;Tiptap.vue&lt;/strong&gt; would look like.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Finally, when we spin up our app, this is how it looks and behaves. I've deployes this at &lt;a href="https://tiptap-demo.now.sh/" rel="noopener noreferrer"&gt;https://tiptap-demo.now.sh/&lt;/a&gt;. You can play around with it and experience yourself what's what.&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%2Fi%2Fuqxprb0piahmtjm55892.gif" 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%2Fi%2Fuqxprb0piahmtjm55892.gif" alt="Text Editor"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Preview for everything we showed exists except History, it provides functionality for doing &lt;code&gt;ctrl/⌘ + Z&lt;/code&gt; or &lt;code&gt;ctrl/⌘ + Y&lt;/code&gt; to undo/redo. You can try it out yourself at &lt;a href="https://tiptap-demo.now.sh/" rel="noopener noreferrer"&gt;https://tiptap-demo.now.sh/&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;One of the great things about Tiptap is that it has keyboard shortcuts implemented out of the box. For instance bold can be activated/inactivated with &lt;code&gt;ctrl/⌘ + B&lt;/code&gt;, italic with &lt;code&gt;ctrl/⌘ + I&lt;/code&gt; and underline with &lt;code&gt;ctrl/⌘ + U&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We have power to customize keyboard shortcuts when we write extensions but that part is out of scope for this post.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;What we did in this post is a small part of the functionality that Tiptap or the great Tiptap community has to offer. More in-depth insight into this tech exists on their &lt;a href="https://github.com/ueberdosis/tiptap" rel="noopener noreferrer"&gt;GitHub repo&lt;/a&gt;. Not only the maintainers but also the community has great extensions to offer, you can take a look at the &lt;a href="https://github.com/ueberdosis/tiptap/issues/819" rel="noopener noreferrer"&gt;discussion in this GitHub issue&lt;/a&gt;. The community has very cool extensions to offer like&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;KaTex integration&lt;/li&gt;
&lt;li&gt;:emoji: Support&lt;/li&gt;
&lt;li&gt;Code Block with manual language selection&lt;/li&gt;
&lt;li&gt;TextColor, TextAlign, TextHighlight&lt;/li&gt;
&lt;li&gt;Realtime Multi-User editing with Y.js&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you're using famous VueJS Component Frameworks like &lt;a href="https://element.eleme.io/" rel="noopener noreferrer"&gt;ElementUI&lt;/a&gt; or &lt;a href="https://vuetifyjs.com/" rel="noopener noreferrer"&gt;VuetifyJS&lt;/a&gt;, there exist even packages like &lt;a href="https://github.com/Leecason/element-tiptap" rel="noopener noreferrer"&gt;element-tiptap&lt;/a&gt; and &lt;a href="https://github.com/iliyaZelenko/tiptap-vuetify" rel="noopener noreferrer"&gt;tiptap-vuetify&lt;/a&gt; which provide a great deal of abstraction and allow you to integrate tiptap with your project very rapidly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tiptap 2.x
&lt;/h3&gt;

&lt;p&gt;The version of TipTap we used in this post is 1.x but 2.x is coming out soon and with that, we won't be requiring many community extension as the Tiptap team has decided to integrate them in their extension library. Also, Tiptap makes the way of writing extensions easier than ever, so we're going to see more and more opportunities of community developed extensions for tiptap in near future. Moreover, it's a great news for TypeScript lovers(or bad for those who hate TS but their company codebase is in TS and they're still on their way to learn it) that Tiptap 2 is completely rewritten in TypeScript.'&lt;/p&gt;




&lt;p&gt;If you liked this, give a start to the &lt;a href="https://github.com/ueberdosis/tiptap" rel="noopener noreferrer"&gt;Tiptap&lt;/a&gt; and &lt;a href="https://github.com/ProseMirror/prosemirror" rel="noopener noreferrer"&gt;Prosemirror&lt;/a&gt; repository for making experience of rich text editing in browser mind-boggling.&lt;/p&gt;

&lt;p&gt;Also you can find all the source code used in this post at &lt;a href="https://github.com/sereneinserenade/tiptap-demo" rel="noopener noreferrer"&gt;this repository&lt;/a&gt;.&lt;/p&gt;




&lt;p&gt;That's it for this post my fellow coders, see you in the next post !!&lt;/p&gt;




&lt;p&gt;&lt;strong&gt;If this was helpful to you in any way and you'd like to support my work, consider Buying me a ☕️.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.buymeacoffee.com/webdevjeet" rel="noopener noreferrer"&gt; &lt;br&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%2Fi%2Fee4tulpkh0x3zmzadvwl.png"&gt;&lt;br&gt;
&lt;/a&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>vue</category>
      <category>tiptap</category>
      <category>typescript</category>
    </item>
    <item>
      <title>array.map(): A better way 🧐 ?</title>
      <dc:creator>Jeet Mandaliya</dc:creator>
      <pubDate>Fri, 29 Jan 2021 18:35:38 +0000</pubDate>
      <link>https://dev.to/sereneinserenade/array-map-a-better-way-c23</link>
      <guid>https://dev.to/sereneinserenade/array-map-a-better-way-c23</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;The method &lt;code&gt;map()&lt;/code&gt; creates a new array with the values that get returned by calling the function provided to &lt;code&gt;map(anyFunctionHere)&lt;/code&gt; on every element of an array.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The array, on which the &lt;code&gt;map()&lt;/code&gt; is being executed is named as &lt;em&gt;&lt;strong&gt;calling array&lt;/strong&gt;.&lt;/em&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Task
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Given an array with reversed first names, create a new array with the same position of names in the original array but re-reversed(should make sense) first names.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Let's take a look how we could tackle it using &lt;code&gt;for-loop&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayOfNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;anhsirK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nosaJ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nolE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;drawdE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arrayOfReversedNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[];&lt;/span&gt; &lt;span class="c1"&gt;// declaring an empty array to store results.&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;nameIndex&lt;/span&gt; &lt;span class="o"&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;nameIndex&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nx"&gt;arrayOfNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;length&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nx"&gt;nameIndex&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;nameIndex&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// we can reverse a string in JavaScript with String.split("").reverse().join("")&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;reversedFirstName&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arrayOfNames&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nx"&gt;nameIndex&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="nx"&gt;arrayOfReversedNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;push&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;reversedFirstName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// output: [ 'Krishna', 'Jason', 'Elon', 'Edward' ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example, we declared &lt;code&gt;arrayOfReversedNames&lt;/code&gt; and then appended calculated reverse names to that array.&lt;/p&gt;

&lt;p&gt;It's time to solve the same problem, but with the use of &lt;code&gt;map()&lt;/code&gt;method.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;arrayOfNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;anhsirK&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nosaJ&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nolE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;drawdE&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;];&lt;/span&gt;

&lt;span class="c1"&gt;// declaring an empty array to store results.&lt;/span&gt;
&lt;span class="kd"&gt;let&lt;/span&gt; &lt;span class="nx"&gt;arrayOfReversedNames&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;arrayOfNames&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="nx"&gt;firstName&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;return&lt;/span&gt; &lt;span class="nx"&gt;firstName&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt; 

&lt;span class="c1"&gt;// arrayOfReversedNames: [ 'Krishna', 'Jason', 'Elon', 'Edward' ]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We pass in an &lt;em&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/Arrow_functions" rel="noopener noreferrer"&gt;arrow function&lt;/a&gt;&lt;/em&gt; to &lt;code&gt;map()&lt;/code&gt; with an argument &lt;code&gt;firstName&lt;/code&gt;. &lt;code&gt;firstName&lt;/code&gt; will have a different value in each iteration on the elements of the calling array. Here in the first iteration, the value of &lt;code&gt;firstName&lt;/code&gt; would be &lt;code&gt;anhsirK&lt;/code&gt;, &lt;code&gt;nosaJ&lt;/code&gt; in the second iteration, and so on... It's clear that we get the same results because &lt;code&gt;map()&lt;/code&gt; is also doing the same iteration that &lt;code&gt;for-loop&lt;/code&gt; was doing.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;At this point you might ask if both methods are doing the same thing that is iteration over elements of the calling array, shouldn't we use &lt;code&gt;for-loop&lt;/code&gt; instead of &lt;code&gt;map()&lt;/code&gt;? It's more readable and explicitly describes what is being done there.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Well, yes and no.&lt;/strong&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Benefits of using &lt;code&gt;map()&lt;/code&gt; over &lt;code&gt;for-loop&lt;/code&gt;
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Fewer lines of code - mostly better!&lt;/li&gt;
&lt;li&gt;  We get access to individual elements of the calling array directly with an argument in the function passed on to &lt;code&gt;map()&lt;/code&gt; - far easier than always getting values with &lt;code&gt;callingArray[someIndex]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  A certainty that all elements of the array will be iterated with &lt;code&gt;map()&lt;/code&gt; - never deal with wrong indices inside a &lt;code&gt;for-loop&lt;/code&gt; anymore.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All we know at the end of the day is that when we have an array and we want to process every element of that array and store values in a new one, &lt;code&gt;map()&lt;/code&gt; is the way to go.&lt;/p&gt;




&lt;p&gt;This is originally written &lt;a href="https://webdevjeet.me/2020-12-array-prototype-map/" rel="noopener noreferrer"&gt;at my blog&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;Edit:&lt;/p&gt;

&lt;p&gt;Take a look at the comment on this post made by &lt;a href="https://dev.to/brettthurs10"&gt;Brett Thurston&lt;/a&gt; to get more info on where not to use &lt;code&gt;map()&lt;/code&gt; as per MDN.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>typescript</category>
      <category>javascriptarraymethods</category>
    </item>
    <item>
      <title>04 Git: Branches Are Breathtaking 🔥</title>
      <dc:creator>Jeet Mandaliya</dc:creator>
      <pubDate>Thu, 28 Jan 2021 00:51:17 +0000</pubDate>
      <link>https://dev.to/sereneinserenade/04-git-branches-are-breathtaking-1i41</link>
      <guid>https://dev.to/sereneinserenade/04-git-branches-are-breathtaking-1i41</guid>
      <description>&lt;h3&gt;
  
  
  What Are Branches?
&lt;/h3&gt;

&lt;p&gt;Branches are a way of diverging from the main development line and keep working on the project without affecting the main development line ("main development line" refers to mainly &lt;code&gt;master&lt;/code&gt; or &lt;code&gt;main&lt;/code&gt; branch). That means every branch has its own commits which can be different from other branches and they do not meddle in each others stream unless we manually perform operations like merging, rebasing or cherry-picking.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Are Branches Used For?
&lt;/h3&gt;

&lt;p&gt;As branches allow us to work without messing up main development line, branches are used for adding new features, solving bugs, hot fixing a critical bug etc. Basically everything that needs to be isolated at the time of development, uses branching.&lt;/p&gt;

&lt;p&gt;We can have a new branch for every ongoing task, commit changes in that branch and finally when the work is done, we can merge that branch into main development line(in our case &lt;code&gt;master&lt;/code&gt; branch).&lt;/p&gt;

&lt;p&gt;In the &lt;a href="https://webdevjeet.me/tag/git-an-essential-tool-for-devs/" rel="noopener noreferrer"&gt;previous posts in this series&lt;/a&gt;, you might've noticed that there is &lt;code&gt;master&lt;/code&gt; written in the terminal screenshots. That stands for which branch we're currently working on.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs96v69o4gln5hil8mu4v.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fs96v69o4gln5hil8mu4v.jpg" alt="master Is Name Of Current Branch" width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;
`master` Is Name Of Current Branch



&lt;p&gt;Now that we've discussed what Git Branches are and what they're used for, we can move on to how to use them. There are two commands that we generally use to create and navigate through the branches which are &lt;code&gt;git branch&lt;/code&gt; and &lt;code&gt;git checkout&lt;/code&gt;. The latter one can also be used with commits, but for now, we'll use it with branches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command: &lt;code&gt;git branch&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Running &lt;code&gt;git branch&lt;/code&gt; gives you a list of existing branches in the project and the current branch is shown with a &lt;code&gt;*&lt;/code&gt; at the start of its name in the list. Here is &lt;a href="https://github.com/sereneinserenade/first-repo" rel="noopener noreferrer"&gt;the&lt;/a&gt; repository that I am working on for &lt;a href="https://webdevjeet.me/tag/git-an-essential-tool-for-devs/" rel="noopener noreferrer"&gt;this series&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;git branch &amp;lt;name-of-branch&amp;gt;&lt;/code&gt; will create a new branch.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff47vtq4a8jzxl9n4hykm.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ff47vtq4a8jzxl9n4hykm.jpg" alt="git branch " width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;
`git branch "new-list"`



&lt;h3&gt;
  
  
  Command: &lt;code&gt;git checkout &amp;lt;name-of-branch&amp;gt;&lt;/code&gt;
&lt;/h3&gt;

&lt;p&gt;Running &lt;code&gt;git checkout &amp;lt;name-of-branch&amp;gt;&lt;/code&gt; allows us to navigate to the branch name that we provided.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4guc8lkk0qa9ruj1aay7.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F4guc8lkk0qa9ruj1aay7.jpg" alt="git checkout new-list" width="800" height="158"&gt;&lt;/a&gt;&lt;/p&gt;
`git checkout new-list`



&lt;p&gt;We see that running &lt;code&gt;git checkout new-list&lt;/code&gt; switched the branch and when we ran &lt;code&gt;git branch | cat&lt;/code&gt;, the &lt;code&gt;*&lt;/code&gt; is now with &lt;code&gt;new-list&lt;/code&gt; which means that &lt;code&gt;new-list&lt;/code&gt; has become our current branch.&lt;/p&gt;

&lt;p&gt;Now let's add a new list of friends in this branch. Since blog posts and books and are our biggest friends, we're gonna add them before everything.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv2cpbzvhw8icjwjzmo3n.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv2cpbzvhw8icjwjzmo3n.jpg" width="800" height="137"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating the file and writing to it, we can finally commit that file and push it.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6ngea6d5lfyfiab34sb6.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F6ngea6d5lfyfiab34sb6.jpg" alt="git add friends.md &amp;amp;&amp;amp; git commit -m " width="800" height="230"&gt;&lt;/a&gt;&lt;/p&gt;
`git add friends.md &amp;amp;&amp;amp; git commit -m "added friends.md"` and `git push`



&lt;p&gt;We see that there was a fatal error when we ran &lt;code&gt;git push&lt;/code&gt;. The error put in simple words means that the new branch named &lt;code&gt;new-list&lt;/code&gt; doesn't exist in GitHub(remote). And it shows us a suggestion at the end to run to create this branch in GitHub, which is &lt;code&gt;git push --set-upstream origin new-list&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flozp0ngfc2naptmnzput.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Flozp0ngfc2naptmnzput.jpg" alt="git push --set-upstream origin new-list" width="800" height="284"&gt;&lt;/a&gt;&lt;/p&gt;
`git push --set-upstream origin new-list`



&lt;p&gt;The command &lt;code&gt;git push --set-upstream origin new-list&lt;/code&gt; is equivalent to creating a new branch in remote named &lt;code&gt;origin&lt;/code&gt; and pushing our new local commit to that remote branch.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The thing to keep in mind is that whenever we create a branch with &lt;code&gt;git branch&lt;/code&gt;, it is only on our machine, we need to push it to remote manually after creating it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Shortcut: &lt;code&gt;git checkout -b &amp;lt;name-of-new-branch&amp;gt;&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;Running &lt;code&gt;git checkout -b &amp;lt;name-of-new-branch&amp;gt;&lt;/code&gt; will not only create a new branch but also navigate to that new branch so you don't have to run &lt;code&gt;git branch &amp;lt;name-of-new-branch&amp;gt;&lt;/code&gt; and then &lt;code&gt;git checkout &amp;lt;name-of-new-branch&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhc8edv4bu6g7uficawg1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhc8edv4bu6g7uficawg1.jpg" alt="git checkout -b " width="800" height="165"&gt;&lt;/a&gt;&lt;/p&gt;
`git checkout -b "checkout-b-test"`



&lt;p&gt;&lt;strong&gt;Yay 🧨🧨🧨, now you know how to create branches and switch between them, and a shortcut that does both by default!&lt;/strong&gt;&lt;/p&gt;




&lt;p&gt;This post is originally written &lt;a href="https://webdevjeet.me/2021-01-04-git-branches-are-breathtaking/" rel="noopener noreferrer"&gt;on my blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
      <category>webdev</category>
    </item>
    <item>
      <title>03 Git: Pull - Getting The Remote Changes</title>
      <dc:creator>Jeet Mandaliya</dc:creator>
      <pubDate>Thu, 28 Jan 2021 00:43:16 +0000</pubDate>
      <link>https://dev.to/sereneinserenade/03-git-pull-getting-the-remote-changes-5e7p</link>
      <guid>https://dev.to/sereneinserenade/03-git-pull-getting-the-remote-changes-5e7p</guid>
      <description>&lt;p&gt;This post falls in the series &lt;a href="https://webdevjeet.me/tag/git-an-essential-tool-for-devs/" rel="noopener noreferrer"&gt;Git: An Essential Tool&lt;/a&gt; after &lt;a href="https://webdevjeet.me/2020-12-git-remotes-and-github/" rel="noopener noreferrer"&gt;02 Git: Git Remotes and GitHub&lt;/a&gt;. In that, we discuss what git remotes are and how we can use them to have a remote copy of our Git repo in the code hosting platform for version control and collaboration like &lt;a href="https://github.com" rel="noopener noreferrer"&gt;GitHub&lt;/a&gt;. I would genuinely recommend reading it before reading the current post.&lt;/p&gt;

&lt;h3&gt;
  
  
  Git Pull: Getting Changes From A Remote Server (ex. GitHub)
&lt;/h3&gt;

&lt;p&gt;Many times we require to work collaboratively on a project and make changes to software concurrently. When we're editing files on our machines locally and then pushing it on GitHub, other collaborators might also want to push their code to GitHub to collaborate.&lt;/p&gt;

&lt;p&gt;Git Pull helps us to get the changes done by other collaborators(or by us using GitHub Website). This process can be best explained with help of an example and that's exactly what we're going to do. So let's dig in and go to the repository that we created in &lt;a href="https://webdevjeet.me/2020-12-git-remotes-and-github/" rel="noopener noreferrer"&gt;02 Git: Git Remotes and GitHub&lt;/a&gt;. In my case, it would be &lt;a href="https://github.com/sereneinserenade/first-repo" rel="noopener noreferrer"&gt;this&lt;/a&gt;. Here is what we are going to do.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Add a new file named &lt;code&gt;README.md&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  Add dummy content to it.&lt;/li&gt;
&lt;li&gt;  Git Pull to get &lt;code&gt;README.md&lt;/code&gt; that we created.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  GitHub: Adding A New File To Repo
&lt;/h3&gt;

&lt;p&gt;On visiting repo on GitHub, we see the view of repo which has an &lt;code&gt;Add File&lt;/code&gt; dropdown button in the middle of the top-right controls section.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm6lzh35yln58il904n4q.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm6lzh35yln58il904n4q.jpg" width="800" height="221"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Two options &lt;code&gt;Create new file&lt;/code&gt; and &lt;code&gt;Upload files&lt;/code&gt; are visible in the dropdown. For the sake of simplicity, we're gonna go for &lt;code&gt;Create new file&lt;/code&gt;. On hitting that button, we're gonna be redirected to a page that looks like the following.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv73oemwas63vrr8idfqz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv73oemwas63vrr8idfqz.jpg" width="800" height="120"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As mentioned in the list of things to do, we're going to name the file &lt;code&gt;README.md&lt;/code&gt;. There is a noble reason for it that is fused with the default repository view of GitHub, which we'll see at the end. Following is the text, that is written in the content section.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# first-repo
&amp;gt; This repo is for the [series Git: An Essential Tool](https://webdevjeet.me/tag/git-an-essential-tool-for-devs/)  on [My Blog](https://webdevjeet.me)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The extension &lt;code&gt;.md&lt;/code&gt; stands for &lt;code&gt;MarkDown&lt;/code&gt; format. GitHub has great resources on basic markdown format &lt;a href="https://docs.github.com/en/free-pro-team@latest/github/writing-on-github/basic-writing-and-formatting-syntax" rel="noopener noreferrer"&gt;here&lt;/a&gt;. If we like, we can also see the preview of our markdown that we wrote in the &lt;code&gt;Edit new file&lt;/code&gt; section rendered directly inside the &lt;code&gt;Preview&lt;/code&gt; tab. Here's what it looks like.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj8gkz0gnatyjshfz0rdu.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fj8gkz0gnatyjshfz0rdu.jpg" width="800" height="146"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After adding content in &lt;code&gt;README.md&lt;/code&gt; as per our willingness, we can continue with committing the file. Add any commit message you like, here I've written &lt;code&gt;++ README.md&lt;/code&gt; which is my way of writing commit messages, with which I immediately recognize that we added a new file named &lt;code&gt;README.md&lt;/code&gt; in this commit. Since we'd discuss branches later in its specific post, that focuses on branches, we're gonna leave the first radio &lt;code&gt;Commit directly to the master branch&lt;/code&gt; Selected.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1ftrjz77uwfbc0rntnp0.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F1ftrjz77uwfbc0rntnp0.jpg" width="800" height="219"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;As soon as we click on &lt;code&gt;Commit new file&lt;/code&gt; we'll be redirected to the home page of the repo, but this time, GitHub has a slight new surprise ready for us as mentioned before.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9xk0g40b7k26dqrx4n5m.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9xk0g40b7k26dqrx4n5m.jpg" alt="Repository View After Adding README.md" width="800" height="359"&gt;&lt;/a&gt;&lt;/p&gt;
Repository View After Adding `README.md`



&lt;p&gt;That's right, GitHub shows the content of &lt;code&gt;README.md&lt;/code&gt; in the root directory of the repo rendered on the repo page by default. &lt;code&gt;README.md&lt;/code&gt; is in the general run of things used to show information about the repo and that's the exact thing we did here too!&lt;/p&gt;

&lt;h3&gt;
  
  
  Command: Git Pull
&lt;/h3&gt;

&lt;p&gt;Now that we've added the file on GitHub, we can go to our code and run &lt;code&gt;git pull&lt;/code&gt; to update the state of the repository to be in sync with the state of the repo on GitHub.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn0o7pm58us8d0zuw85on.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fn0o7pm58us8d0zuw85on.jpg" width="800" height="151"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Running &lt;code&gt;git pull&lt;/code&gt; will always show which files have been added or modified alongside with total numbers of lines added/modified in a particular file. In our case, we can see something like &lt;code&gt;README.md | 3 +++&lt;/code&gt; which means &lt;code&gt;README.md&lt;/code&gt; file had changes in 3 lines and &lt;code&gt;+++&lt;/code&gt; means all of them were additions and not modifications. No modifications also make perfect sense because we added this file for the first time to our project.&lt;/p&gt;

&lt;p&gt;Git pull updates local repo with the new information of remote repo and that allows us to not only fetch changes done in GitHub website by us but also changes done by other collaborators in GitHub. And in most cases, you will find yourself getting changes from collaborators because we rarely edit/create/upload files from GitHub as we can do it far better with help of commands like &lt;code&gt;git push&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Whoopee ✅ , now you know how to update your local repo with the latest changes with&lt;/strong&gt; &lt;code&gt;**git pull**&lt;/code&gt; &lt;strong&gt;!!!🔥&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next post in the series is &lt;a href="https://webdevjeet.me/2021-01-04-git-branches-are-breathtaking/" rel="noopener noreferrer"&gt;04 Git: Branches Are Breathtaking 🔥&lt;/a&gt; where we talk about what Git Branches are and what problems they solve while collaborating.&lt;/p&gt;




&lt;p&gt;This post is originally written &lt;a href="https://webdevjeet.me/2021-01-git-pull-getting-the-remote-changes/" rel="noopener noreferrer"&gt;on my blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>github</category>
      <category>git</category>
    </item>
    <item>
      <title>02 Git: Git Remotes and GitHub</title>
      <dc:creator>Jeet Mandaliya</dc:creator>
      <pubDate>Thu, 28 Jan 2021 00:34:00 +0000</pubDate>
      <link>https://dev.to/sereneinserenade/02-git-git-remotes-and-github-2hbo</link>
      <guid>https://dev.to/sereneinserenade/02-git-git-remotes-and-github-2hbo</guid>
      <description>&lt;p&gt;This post falls in the series after &lt;a href="https://webdevjeet.me/git-basics/" rel="noopener noreferrer"&gt;01 Git: Basics&lt;/a&gt; in the &lt;a href="https://webdevjeet.me/tag/git-an-essential-tool-for-devs/" rel="noopener noreferrer"&gt;series&lt;/a&gt;. If you haven't read it or wanna brush up your Git skills, consider giving &lt;a href="https://webdevjeet.me/2020-12-git-basics/" rel="noopener noreferrer"&gt;it&lt;/a&gt; a shot first 🚀.&lt;/p&gt;

&lt;p&gt;In the above-mentioned post, we discussed basic Git concepts like initializing a Git repository(abbr. "repo"), creating a commit, and getting info about differences in files. All those were being done only on our machine only.&lt;/p&gt;

&lt;p&gt;In this post, we're gonna take a look at how to manage remotes, which allow us to maintain a copy of our Git repository in a remote server. There are countless benefits of having a remote repository for Git, some are listed below.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  Ability to have collaborators/contributors on our project from across the globe.&lt;/li&gt;
&lt;li&gt;  Perform automated actions like deploying a new version of our software, checking code-quality of our software, and much more.&lt;/li&gt;
&lt;li&gt;  Show your projects to the world with a simple &lt;code&gt;git push&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;  Always have a copy of your code on a remote server and never lose it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Creating A Remote Repository With GitHub
&lt;/h3&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;GitHub&lt;/strong&gt; is a code hosting platform for version control and collaboration.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;If you don't have an account on GitHub, it can be created &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Once it's done and you are already on the &lt;a href="https://github.com/" rel="noopener noreferrer"&gt;homepage&lt;/a&gt;, a new repository can be created with the option in dropdown named "+" in the top-right corner of the nav-bar.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo9j77anueg5qid9tc6rj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fo9j77anueg5qid9tc6rj.jpg" width="508" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Alternatively visiting &lt;a href="https://github.com/new" rel="noopener noreferrer"&gt;https://github.com/new&lt;/a&gt; will take us to the create new repo page. Once you're on that page, you should see something similar to the following.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg2bp0fri5dotl6qk5ig1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fg2bp0fri5dotl6qk5ig1.jpg" alt="https://github.com/new" width="800" height="900"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;a href="https://github.com/new" rel="noopener noreferrer"&gt;&lt;/a&gt;https://github.com/new



&lt;p&gt;You can make the repository private/public according to your choice. For now, we're going to leave all the options in "&lt;em&gt;Initialize this repository with&lt;/em&gt;" unchecked. After hitting the "create repository" button, we'll be taken to the repo page. There you can see configurations about pushing an existing repo from Command-Line-Interface(abbr. "CLI").&lt;/p&gt;

&lt;p&gt;Three ways to push to the repository are mentioned here. For the scope of this post, we'll focus on the first two only.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhlcj8vy9k3ils52221uj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fhlcj8vy9k3ils52221uj.jpg" width="800" height="461"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Pushing After Creating A New Repo via CLI
&lt;/h3&gt;

&lt;p&gt;We had a thorough discussion about initializing a git repo via CLI and committing files in our previous post &lt;a href="https://webdevjeet.me/2020-12-git-basics/" rel="noopener noreferrer"&gt;01 Git: Basics&lt;/a&gt;. Once we're done with initializing the Git repo locally and committing at least once, we can focus on pushing our repository to GitHub. Now comes the part where we configure the GitHub as our &lt;code&gt;origin&lt;/code&gt; remote in our local Git repo. We can have multiple remotes configured in our local repo and &lt;code&gt;origin&lt;/code&gt; is the default remote. When we don't specify any remote while executing Git commands, it's going to operate with &lt;code&gt;origin&lt;/code&gt; remote by default.&lt;/p&gt;

&lt;p&gt;To list all the remotes we can run &lt;code&gt;git remote -v&lt;/code&gt;. Right now as we won't have any remotes configured, it'll output nothing. Now we can add the origin remote by writing the following command.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git remote add origin https://github.com/sereneinserenade/first-repo.git
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As mentioned earlier, to list the remotes, we can run &lt;code&gt;git remote -v&lt;/code&gt;. This time, it'll show us the remote we added.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9qb8o8aw58jvff3al0pl.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F9qb8o8aw58jvff3al0pl.jpg" width="800" height="126"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;On the 2&lt;sup&gt;nd&lt;/sup&gt; line, we see that our push config is set to &lt;code&gt;https://github.com/sereneinserenade/first-repo.git&lt;/code&gt;. Pushing to origin can be done with &lt;code&gt;git push origin master&lt;/code&gt;. Notice that we've added remote with &lt;code&gt;HTTP&lt;/code&gt;, thus Git will ask for username and password for GitHub when we will be pushing our repo.&lt;/p&gt;

&lt;p&gt;As an alternative to that, we can use &lt;code&gt;ssh&lt;/code&gt; and configure &lt;a href="https://en.wikipedia.org/wiki/SSH_(Secure_Shell)" rel="noopener noreferrer"&gt;SSH&lt;/a&gt; key for GitHub and use it as an authentication method. A comprehensive guide on how to generate an ssh-key and add it to your GitHub account can be found &lt;a href="https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/connecting-to-github-with-ssh" rel="noopener noreferrer"&gt;here&lt;/a&gt;. You'll be required to &lt;a href="https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent" rel="noopener noreferrer"&gt;generate an ssh-key&lt;/a&gt; first and then you can &lt;a href="https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account" rel="noopener noreferrer"&gt;add it to your GitHub&lt;/a&gt; account. In the "&lt;a href="https://docs.github.com/en/free-pro-team@latest/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account" rel="noopener noreferrer"&gt;Adding a new SSH key to your GitHub account&lt;/a&gt;" they use commands like &lt;code&gt;pbcopy&lt;/code&gt; or &lt;code&gt;xclip&lt;/code&gt;. We can simply do it by using &lt;code&gt;echo ~/.ssh/id_ed25519.pub&lt;/code&gt; and then copying output to the clipboard manually with &lt;code&gt;ctrl/cmd + c&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But before all that, configuring git is better since it allows other collaborators to identify the author of specific commits. Configuring Git requires the Name and Email of the Git User to be configured. Following would help in configuring.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git config --global user.name "&amp;lt;YOUR NAME HERE&amp;gt;"
git config --global user.email "&amp;lt;YOUR PUBLIC_EMAIL HERE&amp;gt;"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I already have an SSH key for GitHub configured on my machine, and I will be continuing with that. When we use &lt;code&gt;ssh&lt;/code&gt;, we also need to configure our remote as &lt;code&gt;git@github.com:sereneinserenade/first-repo.git&lt;/code&gt; as mentioned below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F50810xkme7oyloy27mfp.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2F50810xkme7oyloy27mfp.jpg" width="800" height="193"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;We can finally push it by using &lt;code&gt;git push origin master&lt;/code&gt; as mentioned earlier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa3zuzlngeyaz754ix2yz.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fa3zuzlngeyaz754ix2yz.jpg" width="800" height="177"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Focusing on the last line of output, we see &lt;code&gt;master -&amp;gt; master&lt;/code&gt; which basically means that we pushed the local branch &lt;code&gt;master&lt;/code&gt; to the remote branch &lt;code&gt;master&lt;/code&gt; or &lt;code&gt;origin/master&lt;/code&gt;. We will be discussing Git Branches in its own post, for now, the only thing to keep in mind is that in a repo generated by &lt;code&gt;git init&lt;/code&gt;, the default branch is &lt;code&gt;master&lt;/code&gt; or &lt;code&gt;main&lt;/code&gt; and we push it to remote respectively with their names, i.e if the output of &lt;code&gt;git branch&lt;/code&gt; is &lt;code&gt;master&lt;/code&gt;, we can push it with &lt;code&gt;git push origin master&lt;/code&gt; and if it's &lt;code&gt;main&lt;/code&gt;, we can push it by &lt;code&gt;git push origin main&lt;/code&gt;.  &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;That's it! We've pushed the repo and we can see in GitHub that our file&lt;/strong&gt; &lt;code&gt;**learnings.md**&lt;/code&gt; &lt;strong&gt;was also uploaded 🚀.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwld36sy2fu1rg4rqfdpk.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fwld36sy2fu1rg4rqfdpk.jpg" alt="GitHub Repository Page After Pushing" width="800" height="223"&gt;&lt;/a&gt;&lt;/p&gt;
GitHub Repository Page After Pushing



&lt;h3&gt;
  
  
  What We Discussed In This Iteration:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  Knowing what are Git Remotes - done!&lt;/li&gt;
&lt;li&gt;  How to Create a New Repository on GitHub - done!&lt;/li&gt;
&lt;li&gt;  How to Configure SSH key for GitHub - done!&lt;/li&gt;
&lt;li&gt;  How to add Git Remotes to our local copy of repo - done!&lt;/li&gt;
&lt;li&gt;  Pushing our local repo to GitHub - done!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Alrighty then 🚀, now you know how to work with Git Remotes and GitHub to keep your code online!!!&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next post in this series is &lt;a href="https://webdevjeet.me/2021-01-git-pull-getting-the-remote-changes/" rel="noopener noreferrer"&gt;03 Git: Pull - Getting The Remote Changes&lt;/a&gt; where we talk about how to do changes in GitHub UI and fetch them to our local machine.&lt;/p&gt;




&lt;p&gt;This post is originally written &lt;a href="https://webdevjeet.me/2020-12-git-remotes-and-github/" rel="noopener noreferrer"&gt;on my blog&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
    <item>
      <title>01 Git: Basics</title>
      <dc:creator>Jeet Mandaliya</dc:creator>
      <pubDate>Thu, 28 Jan 2021 00:20:48 +0000</pubDate>
      <link>https://dev.to/sereneinserenade/01-git-basics-4g9j</link>
      <guid>https://dev.to/sereneinserenade/01-git-basics-4g9j</guid>
      <description>&lt;h3&gt;
  
  
  What is Git and why has it become a must in the current software development world?
&lt;/h3&gt;

&lt;p&gt;&lt;a href="https://git-scm.com" rel="noopener noreferrer"&gt;Git&lt;/a&gt; is an open-source, distributed version control system created initially by &lt;a href="https://github.com/torvalds" rel="noopener noreferrer"&gt;Linus Torvalds&lt;/a&gt;, creator of &lt;a href="https://en.wikipedia.org/wiki/Linux" rel="noopener noreferrer"&gt;Linux&lt;/a&gt; (&amp;amp; Git). You might be wondering what is a &lt;em&gt;&lt;a href="https://en.wikipedia.org/wiki/Version_control" rel="noopener noreferrer"&gt;Version Control (or Source Control) System&lt;/a&gt;.&lt;/em&gt; Well, in the world of software development today, versioning the software has become essential as it helps developers to keep track of new changes being done to the software and allows developers to collaborate on it. Also if something goes wrong, they can roll-back to the last stable version.&lt;/p&gt;

&lt;p&gt;Knowing the purpose of Git, we can move on to how to use Git to build awesome pieces of software. The official installation guide is &lt;a href="https://git-scm.com/book/en/v2/Getting-Started-Installing-Git" rel="noopener noreferrer"&gt;here&lt;/a&gt;. To use Git, first of all, we have to open a terminal and change our present working directory(aka pwd) to the directory where we want to start using Git. In Unix/Linux based systems, command &lt;code&gt;cd&lt;/code&gt; will do what we want.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;cd ~/path/to/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once we're inside of target directory, we have to initialize the Git repo. We can do so by running the following in the terminal.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git init
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Here is output of &lt;code&gt;git init&lt;/code&gt; on successful execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Initialized empty Git repository in ~/path/to/directory
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We discussed earlier that Git keeps track of changes in files of our project. From "tracking", there are two states of files inside a Git initialized directory. One is &lt;strong&gt;tracked&lt;/strong&gt; by Git and the other, as you might've guessed, is &lt;strong&gt;untracked&lt;/strong&gt;. To understand the concept of tracked and untracked files, we must have some files first. If the directory is empty, we can create a file and add some text to it directly by using &lt;code&gt;echo&lt;/code&gt; command on Unix/Linux-based systems.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "1\. Learning Git and Github" &amp;gt; ./learnings.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;&amp;gt;&lt;/code&gt; creates a new file named &lt;code&gt;learnings.me&lt;/code&gt; and puts the output of &lt;code&gt;echo&lt;/code&gt; in that file. Now as soon as we create this file, we can execute &lt;code&gt;git status&lt;/code&gt; in the terminal to know the status of our tracked/untracked files.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxjh6mpkoq7s0qywqtbrr.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fxjh6mpkoq7s0qywqtbrr.jpg" alt="Output of git status" width="800" height="239"&gt;&lt;/a&gt;&lt;/p&gt;
Output of `git status`



&lt;p&gt;Ignoring all other information, when we set an eye on the section of &lt;em&gt;Untracked Files&lt;/em&gt;, we see that there is our file named &lt;code&gt;learnings.md&lt;/code&gt;. I.e. Git recognized the fact that the file is new and there has never been a version of this file stored inside of Git and that makes the file &lt;strong&gt;untracked&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Command: Git Add
&lt;/h3&gt;

&lt;p&gt;Once the file is on the list of Untracked Files, we much move the files to the Git state of &lt;em&gt;Staged Files,&lt;/em&gt; where Git lists files that we changed the content of to update our software. In our case, we created a new file (&lt;code&gt;learnings.md&lt;/code&gt;), which will be added to the list of &lt;em&gt;Staged Files&lt;/em&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git add learnings.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As discussed earlier, to know the status of Git tracked/untracked files, we run &lt;code&gt;git status&lt;/code&gt;. Here is what Git will show us now once we've run &lt;code&gt;git add learnings.md&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--CroD8jNW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://webdevjeet.me/content/images/2020/12/image-3.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--CroD8jNW--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_800/https://webdevjeet.me/content/images/2020/12/image-3.jpg" width="800" height="247"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Command: Git Commit
&lt;/h3&gt;

&lt;p&gt;Now we can see that our file is listed under the &lt;em&gt;Changes to be committed(aka staged file-state)&lt;/em&gt; section. Once files are staged(ready to be committed), we can tell Git to take a snapshot of the current state of files with &lt;code&gt;git commit&lt;/code&gt;. In general, we provide a meaningful message(aka Commit-Message) with every commit, so that we can look back at commits later and recognize the changes done in a specific commit. We provide our Commit-Message with an &lt;code&gt;-m&lt;/code&gt; flag with &lt;code&gt;git commit&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;git commit -m "added list of techs in learnings.md"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm66c63a8pckhuijqnvlh.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fm66c63a8pckhuijqnvlh.jpg" alt="Output of git commit -m " width="800" height="168"&gt;&lt;/a&gt;&lt;/p&gt;
Output of `git commit -m "added list of techs in learnings.md"`



&lt;p&gt;Git has taken a snapshot of current files in the directory and since this is the first commit, it is labeled as "root-commit". We discussed earlier that the main application of Git is to keep track of changes in our files. So now it's time to change the content of the file we created earlier. In Unix/Linux systems, we can use &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; with &lt;code&gt;echo&lt;/code&gt; to append the content at the end of a file making (more info on &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; &lt;a href="https://superuser.com/questions/1334939/what-does-mean-in-terminal-command" rel="noopener noreferrer"&gt;here&lt;/a&gt;) a &lt;em&gt;change&lt;/em&gt; to the file and that's where Git kicks in.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;echo "2\. ReactJS and VueJS" &amp;gt;&amp;gt; learnings.md
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We can use &lt;code&gt;cat&lt;/code&gt; command to print the content of a file in the terminal in Unix/Linux systems. And we see that the file's been updated with a new line containing "2. ReactJS and VueJS".&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffuf0xwrbhdokfwswegse.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ffuf0xwrbhdokfwswegse.jpg" width="800" height="114"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Command: Git Diff
&lt;/h3&gt;

&lt;p&gt;Now that we have an updated file that we once committed into Git earlier, we can ask Git to show us differences between the earlier committed(saved) version and the current updated file with the command &lt;code&gt;git diff&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft7j7ym4sblqus7idagpj.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Ft7j7ym4sblqus7idagpj.jpg" alt="Output of git diff" width="636" height="286"&gt;&lt;/a&gt;&lt;/p&gt;
Output of `git diff`



&lt;p&gt;Git diff shows us a green line with a "+" at the start. It stands for the fact that the content that was added to the file is new. Once again we can commit these changes to make a snapshot of the current state of git. Running &lt;code&gt;git add learnings.md&lt;/code&gt; and &lt;code&gt;git commit -m "added ReactJS and VueJS to the learnings list"&lt;/code&gt; subsequently would stage and commit our new change in the file. We can see the list of commits by executing &lt;code&gt;git log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpfa60kbqjyf0849tl4hq.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fpfa60kbqjyf0849tl4hq.jpg" alt="Output of git log" width="800" height="275"&gt;&lt;/a&gt;&lt;/p&gt;
Output of `git log`



&lt;p&gt;If we wish to be informed about the Commit-Messages only, we can use &lt;code&gt;--oneline&lt;/code&gt; with &lt;code&gt;git log&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv8x5uzj6ivfegyyl9kc5.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fi%2Fv8x5uzj6ivfegyyl9kc5.jpg" alt="Output of git log --oneline" width="800" height="94"&gt;&lt;/a&gt;&lt;/p&gt;
Output of `git log --oneline`



&lt;h3&gt;
  
  
  Quick Revision Of Topics Discussed Till Now:
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;  initializing git in a directory with &lt;code&gt;git init&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  staging files with &lt;code&gt;git add &amp;lt;File Name&amp;gt;&lt;/code&gt;  &lt;/li&gt;
&lt;li&gt;  committing them with &lt;code&gt;git commit -m "meaningful-commit-message"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  see the difference between the current state of files and the last committed version of files with &lt;code&gt;git diff&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;  see the information about the commits with &lt;code&gt;git log&lt;/code&gt; or &lt;code&gt;git log --oneline&lt;/code&gt;(for compact info)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Hurray 👏 👏 👏 , now you know how git operations that developers do 1000s of time in a typical year are done!!! 🥳&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Next post in this series is &lt;a href="https://webdevjeet.me/2020-12-git-remotes-and-github/" rel="noopener noreferrer"&gt;02 Git Remotes and GitHub&lt;/a&gt; where we go deep into pushing repos to GitHub and manage remotes to local git repo.&lt;/p&gt;




&lt;p&gt;This post is originally written &lt;a href="https://webdevjeet.me/2020-12-git-basics/" rel="noopener noreferrer"&gt;on my blog.&lt;/a&gt;&lt;/p&gt;

</description>
      <category>git</category>
      <category>github</category>
    </item>
  </channel>
</rss>
