<?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: Joshua Cerbito</title>
    <description>The latest articles on DEV Community by Joshua Cerbito (@cerbito).</description>
    <link>https://dev.to/cerbito</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%2F362279%2Feddf0e41-875f-400b-98f7-1aabdf0c6cf2.jpeg</url>
      <title>DEV Community: Joshua Cerbito</title>
      <link>https://dev.to/cerbito</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/cerbito"/>
    <language>en</language>
    <item>
      <title>002 - Forced Myself to Launch My Site For A /uses Page (CCwF 2021)</title>
      <dc:creator>Joshua Cerbito</dc:creator>
      <pubDate>Sun, 18 Apr 2021 04:10:40 +0000</pubDate>
      <link>https://dev.to/cerbito/002-forced-myself-to-launch-my-site-for-a-uses-page-ccwf-2021-4l2o</link>
      <guid>https://dev.to/cerbito/002-forced-myself-to-launch-my-site-for-a-uses-page-ccwf-2021-4l2o</guid>
      <description>&lt;p&gt;👋 Hello again! And welcome back to the "Coding Challenges with Friends" series. If you're interested in the said series, you may want to check out the first two posts (Part 0, Part 1). Enjoy!&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;There are no code snippets in this post, so if you just want to look at the output, you may simply scroll past the following wall of text and click the links below. 👌 &lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The second challenge was inspired by Wes Bos' &lt;a href="https://uses.tech"&gt;uses.tech&lt;/a&gt;, which in a sense is an extension of his &lt;a href="https://wesbos.com/uses"&gt;/uses&lt;/a&gt; page. Compared to the last challenge, this one is objectively easier since it's technically just a page with a bunch of lists. But for a lazy-ass person like me, the most difficult part of doing a &lt;code&gt;/uses&lt;/code&gt; page is that part that comes before the &lt;code&gt;/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;I could've easily just created a blank webapp with a /uses page, get a random domain name from vercel, and call it a day. But I wanted to finish the challenge properly. And in keeping with the CCwF tradition, I had to do something I've never done before, so here's a list things that I've done for the first time:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Use &lt;a href="https://nextjs.org/"&gt;Next.js&lt;/a&gt; - React is my comfort place, and for these challenges, I really wanted to stay away from it to force myself to learn new things. But the combination of &lt;a href="https://medium.com/@baphemot/whats-server-side-rendering-and-do-i-need-it-cb42dc059b38"&gt;SSR&lt;/a&gt;, fantastic routing and history management, and no-hassle deployment to Vercel was hard to say no to. And since I haven't used Next.js before, I decided to give myself a free React-pass this time around.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Use &lt;a href="https://www.framer.com/motion/"&gt;Framer Motion&lt;/a&gt; - I've been seeing this library for quite a while now but never had the chance to use it until now. Thanks to its &lt;code&gt;AnimatedSharedLayout&lt;/code&gt;, I was able to make page-to-page layout transitions without re-rendering (and therefore resetting) my animated background.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Launch my personal site. That's right. In my 12 years as a professional Web Developer &amp;amp; Designer, I've never, not once, launched a personal site. It's the usual cycle of starting the said project based on a general idea, then trying to implement the best tech approach available, then procrastinating, and then going back to the project after a few months only to realize that the codebase already looks dated. But not today.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For someone my age and in an agency role that's more managerial than creative, I can easily not care about these things anymore and expect to have a relatively stable life. But I'm glad that I have friends who challenge me to do new things and to never stop growing. And speaking of these friends, they also finished the challenge! So if you're interested in our sites or the things that we use on a daily basis, try visiting the links below.&lt;/p&gt;

&lt;p&gt;Mine - &lt;a href="https://www.cerbito.com"&gt;cerbito.com&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/eacayan"&gt;Ellice&lt;/a&gt;'s - &lt;a href="https://www.acayan.xyz"&gt;acayan.xyz&lt;/a&gt;&lt;br&gt;
&lt;a href="https://dev.to/oieeaaaa"&gt;Joimee&lt;/a&gt;'s - &lt;a href="https://cajandab.vercel.app/"&gt;cajandab.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You may also want to check out other people's setups over at &lt;a href="https://uses.tech"&gt;uses.tech&lt;/a&gt;. And while you're at it, why not join the challenge and make yours as well? Cheers!&lt;/p&gt;

</description>
      <category>challenge</category>
      <category>webdev</category>
      <category>ccwf2021</category>
    </item>
    <item>
      <title>001 - Coding Challenges with Friends (Making a Markdown Editor)</title>
      <dc:creator>Joshua Cerbito</dc:creator>
      <pubDate>Sat, 27 Feb 2021 15:04:21 +0000</pubDate>
      <link>https://dev.to/cerbito/001-coding-challenges-with-friends-making-a-markdown-editor-n61</link>
      <guid>https://dev.to/cerbito/001-coding-challenges-with-friends-making-a-markdown-editor-n61</guid>
      <description>&lt;p&gt;👋 Hello again! And welcome back to the "Coding Challenges with Friends" series. If you haven't &lt;a href="https://dev.to/cerbito/000-coding-challenges-with-friends-4n98"&gt;read the previous&lt;/a&gt; article, I suggest you go read the first one for context. It'll only take a minute or two.&lt;/p&gt;

&lt;p&gt;So what's the first challenge? It is to &lt;strong&gt;create a Markdown Editor with Live Preview using a library/framework that you've never used before, and to finish it in 24 hours (just to clarify, that's 24 hours total, not 24 hours straight).&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;It'd be great if you can partake of the challenge, and if you choose to do so, please do &lt;a href="https://twitter.com/@joshuacerbito"&gt;tag me on twitter&lt;/a&gt;, or use the tag &lt;a href="https://dev.to/t/ccwf2021"&gt;#ccwf2021&lt;/a&gt; here at dev.to.&lt;/p&gt;

&lt;p&gt;Sounds good? Alright, let's take a look at how I approached the challenge, and let me walk you through some of my thought process during development.&lt;/p&gt;

&lt;h1&gt;
  
  
  Idea #1: All PHP, Sort Of
&lt;/h1&gt;

&lt;p&gt;When we came up with this idea, the first approach that came to mind is to use a JavaScript library/framework like React or Vue. I mean, we're doing real-time stuff, so it makes sense, right? But I've been doing JavaScript development for so long now that I'm afraid I'll experience JavaScript fatigue soon. So I decided to do it in PHP. I also wanted to go back to PHP development since I've been away from it for quite some time, and I wanted to test the new tools available now.&lt;/p&gt;

&lt;p&gt;This idea might sound a bit crazy, especially since one of the requirements is to have real-time markdown preview. And when people talk about real-time stuff on the web, PHP isn't usually part of the discussion.&lt;/p&gt;

&lt;p&gt;Enter Laravel Livewire.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aa8jreBO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oy3ipjaant7ah85zmpkp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aa8jreBO--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oy3ipjaant7ah85zmpkp.png" alt="livewire"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Livewire technically uses JavaScript in the background, but as a developer, you don't need to worry about it any more. You no longer need to write any JavaScript for your components yourself, you can stay in PHP from start to finish. The whole premise of Livewire is to "forget about JS" and to "trust the back-end", which is very promising. So let's dive into it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App #1&lt;/td&gt;
&lt;td&gt;&lt;a href="https://md-livewire.herokuapp.com/"&gt;https://md-livewire.herokuapp.com/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repo #1&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/joshuacerbito/md-livewire"&gt;https://github.com/joshuacerbito/md-livewire&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  The Setup
&lt;/h2&gt;

&lt;p&gt;I used Laravel since Livewire is a Laravel package/library. And to parse the Markdown input, I used a package named Parsedown.&lt;/p&gt;

&lt;p&gt;For the front-end, I used some vanilla JavaScript but only for the download and preview button (only visible on mobile), and then I just ported &lt;a href="https://gist.github.com/joshuacerbito/f9c83400f93bbf4bb997a5633214b69a"&gt;Github's markdown styles&lt;/a&gt; over.&lt;/p&gt;

&lt;p&gt;And to further simplify things, I decided to deploy the app to Heroku. Just slap a Procfile in there and everything's set.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Approach
&lt;/h2&gt;

&lt;p&gt;Developing the app was pretty straightforward. I didn't use any advanced livewire features since I only needed basic data binding.&lt;/p&gt;

&lt;p&gt;I then abstracted the markdown function to another class, which is not something that I really needed to do. I just like the idea of being able to replace Parsedown with a different markdown package without touching my main controller any more.&lt;/p&gt;

&lt;p&gt;The code is so simple that I can just paste the whole controller here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;namespace App\Http\Livewire;

use Livewire\Component;
use App\Classes\MarkdownParser;

class MarkdownEditor extends Component
{
    public $markdown;

    public function render()
    {
        return view('livewire.markdown-editor', [
            'markdown_preview' =&amp;gt; MarkdownParser::parse($this-&amp;gt;markdown)
        ]);
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Our app is Livewire Markdown Editor component is done.&lt;/p&gt;

&lt;h2&gt;
  
  
  So... How is it?
&lt;/h2&gt;

&lt;p&gt;Well, the good news is that it works. I didn't write any Javascript except for the save and preview button (only visible on mobile), and it just magically works.&lt;/p&gt;

&lt;p&gt;The bad news is this: Livewire's magic isn't really magic. The thing making the data-binding work is actually a series of small fetch requests to the PHP server facilitated by Livewire's JavaScript (injected via the &lt;a href="https://github.com/joshuacerbito/md-livewire/blob/3f217c06c2d5b7e00e01a77b85930cd8973f2936/resources/views/layouts/base.blade.php#L21"&gt;&lt;code&gt;@livewireScripts&lt;/code&gt;&lt;/a&gt; directive). This means that the editing experience may greatly vary mainly based on your internet speed, and partly on how powerful your web hosting is. Testing it out on a "Slow 3G" connection made the issue all the more apparent.&lt;/p&gt;

&lt;p&gt;This is a deal-breaker. I can't even start thinking about the other cool features I'd like to implement next. And just to clarify, I'm not taking away anything from Livewire. I still think it's a good alternative approach to building interactive web apps, just not for this one.&lt;/p&gt;

&lt;p&gt;So what now? If we need actual real-time previews, then we need to handle the markdown stuff on the client side. I think you know where this is going...&lt;/p&gt;

&lt;h1&gt;
  
  
  Idea #2: Just JS, I mean "Just JS"
&lt;/h1&gt;

&lt;p&gt;I know, I know. There are lots of ways to go about this, and a lot of libraries and frameworks to choose from like Preact/React, Svelte, Vue, etc. But as I was thinking about what framework to use, I realized that in reality, the only thing that I need help from a library for is parsing and converting markdown (because I'm not that smart to make my own parser). All the other stuff that these famous libraries come with are unnecessary in this context. And using any of those frameworks also meant setting up some build script. There are tools like &lt;code&gt;create-react-app&lt;/code&gt; that take care of those build systems for you, but if I can get away with not using any build scripts, I will. So I did.&lt;/p&gt;

&lt;p&gt;I decided to just pick a well-reviewed &lt;a href="https://github.com/markedjs/marked"&gt;markdown parser library&lt;/a&gt; and then wrote everything using Vanilla JavaScript. This did not only reduce the overall size of the app, but it also made deployment much easier. So let's take a look at it.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App #2&lt;/td&gt;
&lt;td&gt;&lt;a href="https://md-vanilla.herokuapp.com/"&gt;https://md-vanilla.herokuapp.com/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repo #2&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/joshuacerbito/md-vanilla"&gt;https://github.com/joshuacerbito/md-vanilla&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Looking Good, Ey?
&lt;/h2&gt;

&lt;p&gt;Here's the main app's core function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$textarea.addEventListener("keyup", (e) =&amp;gt; {
    $preview.innerHTML = marked(e.target.value);
    localStorage.setItem("md-livewire", e.target.value);
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything feels much more responsive when all the interaction's handled on the client side. This also allowed me to easily tap into the vast array of browser APIs. The one that I reached out for first is &lt;code&gt;localStorage&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The ability to persist data locally made the app feel like an actual product. In fact, I started writing this article in Notion, but proceeded to write the rest using this version of the app.&lt;/p&gt;

&lt;p&gt;So what do we have so far? We have a markdown editor with real-time preview, we also have the ability to persist data locally (meaning, we can close/refresh the tab without losing our document), and we have the ability to download the markdown file if we want to. We can stop here, but I still have a lot of hours left from the 24-hour budget, and at this point, I haven't actually did or used anything new to me, so let's add some more features.&lt;/p&gt;

&lt;h1&gt;
  
  
  Idea #3: Vanilla, but with Icing on Top
&lt;/h1&gt;

&lt;p&gt;I've wanted to create a Progressive Web App since 2018, but whenever I try to write one, something more urgent comes up. But I think now is the time. I think this project is perfect for it. And if you're not familiar with PWA, &lt;a href="https://web.dev/progressive-web-apps/"&gt;this page&lt;/a&gt; is a good starting point.&lt;/p&gt;

&lt;p&gt;The first step to make the app progressive is to make it work offline. I mean, it's a markdown editor, I shouldn't need an internet connection to be able to write markdown documents. So I wrote a small service worker that adds all the necessary assets to cache storage upon registration. Once the service worker's installed, everything should be able to run offline.&lt;/p&gt;

&lt;p&gt;The next step is to make the web app installable on desktop and mobile. For that, we just need a &lt;a href="https://github.com/joshuacerbito/md-vanilla/blob/pwa/manifest.json"&gt;&lt;code&gt;manifest.json&lt;/code&gt;&lt;/a&gt;, add a reference to it along with a couple more meta tags on our markup like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;&amp;lt;meta name="theme-color" content="#1e1e1e"/&amp;gt;
&amp;lt;link rel="manifest" href="/manifest.json"&amp;gt;
&amp;lt;link rel="shortcut icon" type="image/x-icon" href="/favicon.ico"/&amp;gt;
&amp;lt;link rel="apple-touch-startup-image" /&amp;gt;
&amp;lt;link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon.png"&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To install this on your phone, simply navigate to the site then add the page to your home screen, or if you're on the desktop, go to your settings and click the option that says "Install MDfy". Let's take a look at what we have now.&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;&lt;/th&gt;
&lt;th&gt;&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;App #2&lt;/td&gt;
&lt;td&gt;&lt;a href="https://mdfy.herokuapp.com/"&gt;https://mdfy.herokuapp.com/&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Repo #2&lt;/td&gt;
&lt;td&gt;&lt;a href="https://github.com/joshuacerbito/md-vanilla/tree/pwa"&gt;https://github.com/joshuacerbito/md-vanilla/tree/pwa&lt;/a&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;And while I'm at it, I decided to take a look at &lt;a href="https://developers.google.com/web/tools/lighthouse"&gt;Lighthouse&lt;/a&gt; and tried to make everything green.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--wuwuMgxp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwz44vg4yecp8irk2fh2.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--wuwuMgxp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zwz44vg4yecp8irk2fh2.jpg" alt="perf matters"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And with that, the challenge is done! 🎉 There's still a lot of features that I want to add to the app (and a couple of CSS bugs to fix on mobile), but as it is, our web app is already in a very good state. It can persist data locally, it's performant, it's installable, and more importantly it just works! Let's name it "MDfy" (em-di-fai)!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VE7aB09T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8kk59kuoyups2e7nax5v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VE7aB09T--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev-to-uploads.s3.amazonaws.com/uploads/articles/8kk59kuoyups2e7nax5v.png" alt="MDfy"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I'll definitely continue working on this, but I think this is a good stopping point for this challenge. And if you managed to reach this part of the post, then you're awesome and you have my thanks! I hope you learned a thing or two from this one. See you on the next challenge! 🙋‍♂️&lt;/p&gt;

</description>
      <category>challenge</category>
      <category>webdev</category>
      <category>ccwf2021</category>
    </item>
    <item>
      <title>000 - Coding Challenges with Friends</title>
      <dc:creator>Joshua Cerbito</dc:creator>
      <pubDate>Sun, 21 Feb 2021 20:09:24 +0000</pubDate>
      <link>https://dev.to/cerbito/000-coding-challenges-with-friends-4n98</link>
      <guid>https://dev.to/cerbito/000-coding-challenges-with-friends-4n98</guid>
      <description>&lt;p&gt;A couple of months ago, I along with two of my friends decided to form some sort of weekend accountability group. The purpose of the group is not only to help push each other to be better developers/designers, but to be able to have a space where we can discuss things we can't usually talk about at work, and to experiment on technologies that we don't get to use on a daily basis.&lt;/p&gt;

&lt;p&gt;Then a couple of weeks ago, we came up with an idea for a great app (at least we think it's great). In our excitement, we quickly started researching, planning, and designing. It didn't take long before we realized that the scale of the project is much, much bigger than we initially thought. Don't get me wrong, alright. We still think it's a great idea for an app, but with our current individual schedules, it's almost impossible for us to work on something that big right now. So that was a bit of a downer.&lt;/p&gt;

&lt;p&gt;So earlier today, instead of sulking on the fact that we simply don't have that much time and space for it, and to stay true to the purpose of the group, we decided to work on a series of smaller challenges instead. Small projects that we can finish in a month even if we only work on it for 3 hours a week. We thought that a series of smaller victories is much better than erratic and inconsistent bigger victories.&lt;/p&gt;

&lt;p&gt;And that brings us to this series: Coding Challenges with Friends! We came up with an idea that we think is cool, but still small enough to fit a 3-week timeframe. So keep your eyes peeled for Challenge 001 because it's going to be amazing!&lt;/p&gt;

</description>
      <category>challenge</category>
      <category>webdev</category>
      <category>programming</category>
      <category>ccwf2021</category>
    </item>
  </channel>
</rss>
