<?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: Gabriel Diem</title>
    <description>The latest articles on DEV Community by Gabriel Diem (@gabrieldiem).</description>
    <link>https://dev.to/gabrieldiem</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%2F1022114%2F2ccbe25c-60d3-4e73-9c70-8e3439e7af4b.png</url>
      <title>DEV Community: Gabriel Diem</title>
      <link>https://dev.to/gabrieldiem</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/gabrieldiem"/>
    <language>en</language>
    <item>
      <title>How to download Google Meet meeting recordings set to view-only mode</title>
      <dc:creator>Gabriel Diem</dc:creator>
      <pubDate>Tue, 17 Sep 2024 17:40:22 +0000</pubDate>
      <link>https://dev.to/gabrieldiem/how-to-download-google-meet-meeting-recordings-set-to-view-only-mode-4d2a</link>
      <guid>https://dev.to/gabrieldiem/how-to-download-google-meet-meeting-recordings-set-to-view-only-mode-4d2a</guid>
      <description>&lt;p&gt;So you were (or weren't) part of a meeting done with Google Meet that was recorded and the link you have, which is probably the automatic one sent by the Meet app, is set to view-only mode and can't download it straight away with an option the the hamburger menu nor there's a button to do it.&lt;/p&gt;

&lt;p&gt;So how can you do it? It's important to know that the methods going around are not stable in time, given that we try to understand what the Google API's are doing so we can get the video and audio entirely in a common format, e.g. mp4.&lt;/p&gt;

&lt;p&gt;We will review the &lt;strong&gt;previous method&lt;/strong&gt;, &lt;strong&gt;which is not currently working&lt;/strong&gt;, and the &lt;strong&gt;current method&lt;/strong&gt; that &lt;strong&gt;is currently working&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Previous method [not working currently]: downloading videoplayback with the browser's developer tool
&lt;/h2&gt;

&lt;p&gt;When online video meetings exploded in popularity, this method was quickly found. You basically followed these steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the browser's Developer Tools, with right click or via some option in the browser menus.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the Network tab, reload the page, and search for an element called &lt;em&gt;videoplayback&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Right click into it and copy its URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the URL in a new tab and you will see a raw, loaded by the browser,  video with audio that you can download directly with the browser.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It was pretty simple, thought the download speed usually was unstable and it could be slow. But, &lt;strong&gt;it does not work anymore&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Current working method: download video and audio separately with the browser's developer tool
&lt;/h2&gt;

&lt;p&gt;It seems that the Youtube-like player that Google Drive has to play the videos now works with more chunking of the audio and video, in separate channels, so the video chunks arrive by themselves and the audio chunks as well.&lt;/p&gt;

&lt;p&gt;What we are going to do is: get the video file (with no audio), get the audio file, and then join both in a single video (with audio) file with &lt;code&gt;ffmpeg&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting the video file
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the browser's Developer Tools, with right click or via some option in the browser menus.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the Network tab, reload the page, and search for an element called &lt;em&gt;videoplayback&lt;/em&gt;. You will notice that several of these elements keep appearing, this is the chunking I was talking about before.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Right click into one and copy its URL. If you try to download from that URL directly, you won't be able to get the video nor the audio, you will probably download a .txt file if you try.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the URL into a text editor, we are going to remove some parts. The URL looks something like this:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;https://rr5---sn-x1xe55.c.drive.google.com/videoplayback?expire=123456&amp;amp;ei=111_111-aaaaaaaa&amp;amp;ip=111:111:11a:888:5d3f:888:8fed:888&amp;amp;id=aaa123&amp;amp;itag=140&amp;amp;source=webdrive&amp;amp;requiressl=yes&amp;amp;xpc=Eaaa111==&amp;amp;mh=j7&amp;amp;mm=32,26&amp;amp;mn=sn-x1xe7n76,sn-nja7sner&amp;amp;ms=su,onr&amp;amp;mv=m&amp;amp;mvi=5&amp;amp;pl=49&amp;amp;sc=yes&amp;amp;ttl=transient&amp;amp;susc=dr&amp;amp;driveid=111aaa111&amp;amp;app=explorer&amp;amp;eaua=111aaa&amp;amp;mime=video/mp4&amp;amp;vprv=1&amp;amp;prv=1&amp;amp;rqh=1&amp;amp;gir=yes&amp;amp;clen=111222333&amp;amp;dur=111.352&amp;amp;lmt=111222333&amp;amp;mt=111222333&amp;amp;fvip=1&amp;amp;subapp=DRIVE_WEB_FILE_VIEWER&amp;amp;txp=0000224&amp;amp;sparams=expire,ei,ip,id,itag,source,requiressl,xpc,ttl,susc,driveid,app,eaua,mime,vprv,prv,rqh,gir,clen,dur,lmt&amp;amp;sig=111222333-aaa1112223344aaqqbb==&amp;amp;lsparams=mh,mm,mn,ms,mv,mvi,pl,sc&amp;amp;lsig=111222333-aaa1112223344aaqqb&amp;amp;alr=yes&amp;amp;cpn=111aaa&amp;amp;c=WEB_EMBEDDED_PLAYER&amp;amp;cver=1.20240912.01.00&amp;amp;range=1948616-2433307&amp;amp;rn=11&amp;amp;rbuf=119815&amp;amp;ump=1&amp;amp;srfvp=1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;First, we need to locate the &lt;code&gt;mime&lt;/code&gt; attribute and check if what we found is the video or audio:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(...)eaua=111aaa&amp;amp;mime=video/mp4&amp;amp;vprv=1&amp;amp;p(...)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Given that it is &lt;code&gt;mime=video/mp4&lt;/code&gt; we have effectively found the video. If it's not, and it's audio instead, we need to pick another &lt;em&gt;videoplayback&lt;/em&gt; element and repeat until found the video one. It will not work if you manually replace the mime tag, you need to get another element.&lt;/p&gt;

&lt;p&gt;There is a &lt;code&gt;range&lt;/code&gt; attribute in the query string, which we are going to remove, including all the stuff that comes after it.&lt;/p&gt;

&lt;p&gt;Remove the text at the end as shown:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://rr5---sn-x1xe55.c.drive.google.com/videoplayback?expire=123456&amp;amp;ei=111_111-aaaaaaaa&amp;amp;ip=111:111:11a:888:5d3f:888:8fed:888&amp;amp;id=aaa123&amp;amp;itag=140&amp;amp;source=webdrive&amp;amp;requiressl=yes&amp;amp;xpc=Eaaa111==&amp;amp;mh=j7&amp;amp;mm=32,26&amp;amp;mn=sn-x1xe7n76,sn-nja7sner&amp;amp;ms=su,onr&amp;amp;mv=m&amp;amp;mvi=5&amp;amp;pl=49&amp;amp;sc=yes&amp;amp;ttl=transient&amp;amp;susc=dr&amp;amp;driveid=111aaa111&amp;amp;app=explorer&amp;amp;eaua=111aaa&amp;amp;mime=video/mp4&amp;amp;vprv=1&amp;amp;prv=1&amp;amp;rqh=1&amp;amp;gir=yes&amp;amp;clen=111222333&amp;amp;dur=111.352&amp;amp;lmt=111222333&amp;amp;mt=111222333&amp;amp;fvip=1&amp;amp;subapp=DRIVE_WEB_FILE_VIEWER&amp;amp;txp=0000224&amp;amp;sparams=expire,ei,ip,id,itag,source,requiressl,xpc,ttl,susc,driveid,app,eaua,mime,vprv,prv,rqh,gir,clen,dur,lmt&amp;amp;sig=111222333-aaa1112223344aaqqbb==&amp;amp;lsparams=mh,mm,mn,ms,mv,mvi,pl,sc&amp;amp;lsig=111222333-aaa1112223344aaqqb&amp;amp;alr=yes&amp;amp;cpn=111aaa&amp;amp;c=WEB_EMBEDDED_PLAYER&amp;amp;cver=1.20240912.01.00          &amp;lt;&amp;lt;REMOVE FORM THE RIGHT OF THIS&amp;gt;&amp;gt;&amp;amp;range=1948616-2433307&amp;amp;rn=11&amp;amp;rbuf=119815&amp;amp;ump=1&amp;amp;srfvp=1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now with the clean URL we can paste it in a new tab an download the video (with no audio) directly from the browser:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://rr5---sn-x1xe55.c.drive.google.com/videoplayback?expire=123456&amp;amp;ei=111_111-aaaaaaaa&amp;amp;ip=111:111:11a:888:5d3f:888:8fed:888&amp;amp;id=aaa123&amp;amp;itag=140&amp;amp;source=webdrive&amp;amp;requiressl=yes&amp;amp;xpc=Eaaa111==&amp;amp;mh=j7&amp;amp;mm=32,26&amp;amp;mn=sn-x1xe7n76,sn-nja7sner&amp;amp;ms=su,onr&amp;amp;mv=m&amp;amp;mvi=5&amp;amp;pl=49&amp;amp;sc=yes&amp;amp;ttl=transient&amp;amp;susc=dr&amp;amp;driveid=111aaa111&amp;amp;app=explorer&amp;amp;eaua=111aaa&amp;amp;mime=video/mp4&amp;amp;vprv=1&amp;amp;prv=1&amp;amp;rqh=1&amp;amp;gir=yes&amp;amp;clen=111222333&amp;amp;dur=111.352&amp;amp;lmt=111222333&amp;amp;mt=111222333&amp;amp;fvip=1&amp;amp;subapp=DRIVE_WEB_FILE_VIEWER&amp;amp;txp=0000224&amp;amp;sparams=expire,ei,ip,id,itag,source,requiressl,xpc,ttl,susc,driveid,app,eaua,mime,vprv,prv,rqh,gir,clen,dur,lmt&amp;amp;sig=111222333-aaa1112223344aaqqbb==&amp;amp;lsparams=mh,mm,mn,ms,mv,mvi,pl,sc&amp;amp;lsig=111222333-aaa1112223344aaqqb&amp;amp;alr=yes&amp;amp;cpn=111aaa&amp;amp;c=WEB_EMBEDDED_PLAYER&amp;amp;cver=1.20240912.01.00&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Getting the audio file
&lt;/h3&gt;

&lt;p&gt;Same steps that the video file but the mime tag should be &lt;code&gt;audio/mp4&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Open the browser's Developer Tools, with right click or via some option in the browser menus.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Open the Network tab, reload the page, and search for an element called &lt;em&gt;videoplayback&lt;/em&gt;.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Right click into one and copy its URL.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Copy the URL into a text editor, we are going to remove some parts. The URL looks something like this:&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;code&gt;https://rr5---sn-x1xe55.c.drive.google.com/videoplayback?expire=123456&amp;amp;ei=111_111-aaaaaaaa&amp;amp;ip=111:111:11a:888:5d3f:888:8fed:888&amp;amp;id=aaa123&amp;amp;itag=140&amp;amp;source=webdrive&amp;amp;requiressl=yes&amp;amp;xpc=Eaaa111==&amp;amp;mh=j7&amp;amp;mm=32,26&amp;amp;mn=sn-x1xe7n76,sn-nja7sner&amp;amp;ms=su,onr&amp;amp;mv=m&amp;amp;mvi=5&amp;amp;pl=49&amp;amp;sc=yes&amp;amp;ttl=transient&amp;amp;susc=dr&amp;amp;driveid=111aaa111&amp;amp;app=explorer&amp;amp;eaua=111aaa&amp;amp;mime=audio/mp4&amp;amp;vprv=1&amp;amp;prv=1&amp;amp;rqh=1&amp;amp;gir=yes&amp;amp;clen=111222333&amp;amp;dur=111.352&amp;amp;lmt=111222333&amp;amp;mt=111222333&amp;amp;fvip=1&amp;amp;subapp=DRIVE_WEB_FILE_VIEWER&amp;amp;txp=0000224&amp;amp;sparams=expire,ei,ip,id,itag,source,requiressl,xpc,ttl,susc,driveid,app,eaua,mime,vprv,prv,rqh,gir,clen,dur,lmt&amp;amp;sig=111222333-aaa1112223344aaqqbb==&amp;amp;lsparams=mh,mm,mn,ms,mv,mvi,pl,sc&amp;amp;lsig=111222333-aaa1112223344aaqqb&amp;amp;alr=yes&amp;amp;cpn=111aaa&amp;amp;c=WEB_EMBEDDED_PLAYER&amp;amp;cver=1.20240912.01.00&amp;amp;range=1948616-2433307&amp;amp;rn=11&amp;amp;rbuf=119815&amp;amp;ump=1&amp;amp;srfvp=1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;First, we need to locate the &lt;code&gt;mime&lt;/code&gt; attribute and check if what we found is the video or audio:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;(...)eaua=111aaa&amp;amp;mime=audio/mp4&amp;amp;vprv=1&amp;amp;p(...)&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Given that it is &lt;code&gt;mime=audio/mp4&lt;/code&gt; we have effectively found the video. If it's not, and it's video instead, we need to pick another &lt;em&gt;videoplayback&lt;/em&gt; element and repeat until found the video one. It will not work if you manually replace the mime tag, you need to get another element.&lt;/p&gt;

&lt;p&gt;Remove range tag as shown:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://rr5---sn-x1xe55.c.drive.google.com/videoplayback?expire=123456&amp;amp;ei=111_111-aaaaaaaa&amp;amp;ip=111:111:11a:888:5d3f:888:8fed:888&amp;amp;id=aaa123&amp;amp;itag=140&amp;amp;source=webdrive&amp;amp;requiressl=yes&amp;amp;xpc=Eaaa111==&amp;amp;mh=j7&amp;amp;mm=32,26&amp;amp;mn=sn-x1xe7n76,sn-nja7sner&amp;amp;ms=su,onr&amp;amp;mv=m&amp;amp;mvi=5&amp;amp;pl=49&amp;amp;sc=yes&amp;amp;ttl=transient&amp;amp;susc=dr&amp;amp;driveid=111aaa111&amp;amp;app=explorer&amp;amp;eaua=111aaa&amp;amp;mime=audio/mp4&amp;amp;vprv=1&amp;amp;prv=1&amp;amp;rqh=1&amp;amp;gir=yes&amp;amp;clen=111222333&amp;amp;dur=111.352&amp;amp;lmt=111222333&amp;amp;mt=111222333&amp;amp;fvip=1&amp;amp;subapp=DRIVE_WEB_FILE_VIEWER&amp;amp;txp=0000224&amp;amp;sparams=expire,ei,ip,id,itag,source,requiressl,xpc,ttl,susc,driveid,app,eaua,mime,vprv,prv,rqh,gir,clen,dur,lmt&amp;amp;sig=111222333-aaa1112223344aaqqbb==&amp;amp;lsparams=mh,mm,mn,ms,mv,mvi,pl,sc&amp;amp;lsig=111222333-aaa1112223344aaqqb&amp;amp;alr=yes&amp;amp;cpn=111aaa&amp;amp;c=WEB_EMBEDDED_PLAYER&amp;amp;cver=1.20240912.01.00          &amp;lt;&amp;lt;REMOVE FORM THE RIGHT OF THIS&amp;gt;&amp;gt;&amp;amp;range=1948616-2433307&amp;amp;rn=11&amp;amp;rbuf=119815&amp;amp;ump=1&amp;amp;srfvp=1&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Now with the clean URL we can paste it in a new tab an download the audio (with no video) directly from the browser:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;https://rr5---sn-x1xe55.c.drive.google.com/videoplayback?expire=123456&amp;amp;ei=111_111-aaaaaaaa&amp;amp;ip=111:111:11a:888:5d3f:888:8fed:888&amp;amp;id=aaa123&amp;amp;itag=140&amp;amp;source=webdrive&amp;amp;requiressl=yes&amp;amp;xpc=Eaaa111==&amp;amp;mh=j7&amp;amp;mm=32,26&amp;amp;mn=sn-x1xe7n76,sn-nja7sner&amp;amp;ms=su,onr&amp;amp;mv=m&amp;amp;mvi=5&amp;amp;pl=49&amp;amp;sc=yes&amp;amp;ttl=transient&amp;amp;susc=dr&amp;amp;driveid=111aaa111&amp;amp;app=explorer&amp;amp;eaua=111aaa&amp;amp;mime=audio/mp4&amp;amp;vprv=1&amp;amp;prv=1&amp;amp;rqh=1&amp;amp;gir=yes&amp;amp;clen=111222333&amp;amp;dur=111.352&amp;amp;lmt=111222333&amp;amp;mt=111222333&amp;amp;fvip=1&amp;amp;subapp=DRIVE_WEB_FILE_VIEWER&amp;amp;txp=0000224&amp;amp;sparams=expire,ei,ip,id,itag,source,requiressl,xpc,ttl,susc,driveid,app,eaua,mime,vprv,prv,rqh,gir,clen,dur,lmt&amp;amp;sig=111222333-aaa1112223344aaqqbb==&amp;amp;lsparams=mh,mm,mn,ms,mv,mvi,pl,sc&amp;amp;lsig=111222333-aaa1112223344aaqqb&amp;amp;alr=yes&amp;amp;cpn=111aaa&amp;amp;c=WEB_EMBEDDED_PLAYER&amp;amp;cver=1.20240912.01.00&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Combining the video with the audio
&lt;/h3&gt;

&lt;p&gt;So, we have now an .m4a audio file and an .mp4 video file. You will need ffmpeg installed to combine the files into a single video with audio. You can google how to install it into Google, or visit the official site: &lt;a href="https://ffmpeg.org/download.html" rel="noopener noreferrer"&gt;ffmpeg.org/download.html&lt;/a&gt; and check how to get it for your operating system.&lt;/p&gt;

&lt;p&gt;Once you have it, run this simple command to fuse the files into one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ffmpeg -i video.mp4 -i audio.m4a -c:v copy -c:a aac output.mp4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it! Now you have a complete file of the Google Meet recording. I hope it helped!&lt;/p&gt;

</description>
      <category>google</category>
      <category>meeting</category>
      <category>download</category>
      <category>zoom</category>
    </item>
    <item>
      <title>Grub-customizer won't change your GRUB theme in Kali Linux? Try this</title>
      <dc:creator>Gabriel Diem</dc:creator>
      <pubDate>Sat, 01 Jul 2023 22:13:12 +0000</pubDate>
      <link>https://dev.to/gabrieldiem/grub-customizer-wont-change-your-grub-theme-in-kali-linux-try-this-jeb</link>
      <guid>https://dev.to/gabrieldiem/grub-customizer-wont-change-your-grub-theme-in-kali-linux-try-this-jeb</guid>
      <description>&lt;p&gt;If you are familiar with desktop Linux distributions, maybe you are dual booting with another OS, you may have used at some point in time the &lt;code&gt;grub-customizer&lt;/code&gt; program to change the appearance of the GRUB (GRand Unified Bootloader) screen. As a casual Linux user it has been my main way of customizing grub when dual booting Ubuntu with Windows.&lt;/p&gt;

&lt;p&gt;I recently switched laptops and Linux distro to Kali with KDE Plasma and fired grub-customizer as usual. I was surprised to find out that it didn't change the grub theme, despite the grub config file literally using the pre-made theme downloaded from &lt;a href="https://www.gnome-look.org/browse?cat=109"&gt;Gnome-look&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Long story short, after some mostly unfruitful investigation and digging into the grub files spread around my Kali installation I concluded that 3 main files have to be modified in order to effectively have the theme changed and they are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;/boot/grub/grub.cfg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/etc/default/grub&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;/etc/default/grub.d/kali-themes.cfg&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Grub-customizer did change the first file and updated it with the proper &lt;code&gt;theme.txt&lt;/code&gt; location from the theme I downloaded, let's call it &lt;em&gt;myTheme&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;After noticing that I manually changed the GRUB_THEME entry in &lt;code&gt;/etc/default/grub&lt;/code&gt; with the correct theme location, which was &lt;code&gt;/boot/grub/themes/myTheme/theme.txt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then I did the same thing with the &lt;code&gt;/etc/default/grub.d/kali-themes.cfg&lt;/code&gt; file and surprise, surprise, it worked!&lt;/p&gt;

&lt;p&gt;By this point, the grub theme was fully changed and properly adjusted to my liking. There was a little weird thing happening though, after selecting an OS in the grub screen, no matter if it was Kali or Windows, a default Kali theme image was shown for a second or so, which I wanted to change to not show anything and just load the OS. The workaround to solve this was to load a pure black image (all black pixels) before loading the theme in the &lt;code&gt;/etc/default/grub.d/kali-themes.cfg&lt;/code&gt; which I find a little weird because the &lt;code&gt;theme.txt&lt;/code&gt; of &lt;em&gt;myTheme&lt;/em&gt; already defines a background image. Anyway, the file would contain something like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;GRUB_BACKGROUND="/boot/grub/themes/kali/black.png"&lt;br&gt;
GRUB_THEME="/boot/grub/themes/myTheme/theme.txt"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And done! The theme got changed and no weird image flashes disturbed my grub screen, so I was happy with the result 😊.&lt;/p&gt;

</description>
      <category>kali</category>
      <category>linux</category>
      <category>grub</category>
      <category>theme</category>
    </item>
    <item>
      <title>[Solved] React app bundled with Parcel would not deploy correctly in GitHub Pages</title>
      <dc:creator>Gabriel Diem</dc:creator>
      <pubDate>Wed, 08 Feb 2023 20:01:39 +0000</pubDate>
      <link>https://dev.to/gabrieldiem/solved-react-app-bundled-with-parcel-would-not-deploy-correctly-in-github-pages-1pde</link>
      <guid>https://dev.to/gabrieldiem/solved-react-app-bundled-with-parcel-would-not-deploy-correctly-in-github-pages-1pde</guid>
      <description>&lt;p&gt;I was learning ReactJS, making my first dynamic-ish frontend and I was happy enough with that little project as a first React project. It worked perfectly in the local dev server provided by Parcel. I bundled the project and run a simple HTTP Python local server with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="n"&gt;python&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt; &lt;span class="n"&gt;http&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;server&lt;/span&gt; &lt;span class="mi"&gt;3000&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It worked perfectly.&lt;/p&gt;

&lt;p&gt;So I was ready to deploy the app in GitHub Pages, see if I could even do that. I pushed the changes and the &lt;code&gt;dist&lt;/code&gt; folder as well, configured a default GitHub Actions script for a static webapp deployment and waited. It did not work, the js and css files were not being received and the console showed a couple of 404 errors. I found out that the page was trying to pull files from my root url, that being &lt;a href="https://gabrieldiem.github.io"&gt;https://gabrieldiem.github.io&lt;/a&gt;. So I tried making a couple of changes to the GitHub Actions script but I couldn't make it work.&lt;/p&gt;

&lt;p&gt;After that I turned to a package called &lt;a href="https://www.npmjs.com/package/gh-pages"&gt;gh-pages&lt;/a&gt;, which pushed the bundled files to a new branch and deployed the Github Pages website from there, and I gave it a try.&lt;/p&gt;

&lt;p&gt;First I tried deploying a simple create-react-app app to know what I was trying to do was even possible (I was &lt;strong&gt;not&lt;/strong&gt; using create-react-app btw). And it worked! So it had to be something about my bundling config.&lt;/p&gt;

&lt;p&gt;I found out that I had to add to the package.json the entry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"homepage"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"http://gabrieldiem.github.io/Portfolio_like_project"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With &lt;em&gt;Portfolio_like_project&lt;/em&gt; being the repo name. So I bundled the project as I was doing before with the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"parcel build src/index.html"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And set up the gh-pages required scripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"predeploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run build"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"deploy"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"gh-pages -d dist"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I gave it another try, same as before, it did not work again.&lt;br&gt;
Then I tried a couple things with absolute routes and ended up in a GitHub issue of the Parcel repo saying that Parcel and absolute routes don't mix well. So I ditched that. Okay, maybe hardcoding the absolute route directly into the HTML and JS, I ditched that as well (not only because it was awful but also because it didn't work).&lt;/p&gt;

&lt;p&gt;Eventually found out that what could solve my problem was to add a &lt;code&gt;--public-url&lt;/code&gt; flag to the parcel bundle script so it ended looking like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"build"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"parcel build src/index.html --public-url /Portfolio_like_project/"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again, not using absolute routing, instead using the relative route of the root url, which I guessed was &lt;a href="https://gabrieldiem.github.io"&gt;https://gabrieldiem.github.io&lt;/a&gt; so adding the repo name would make the fetching request of the js and css files work properly.&lt;br&gt;
This time it kind of worked. I solved the problem of the requests ending in a 404 error, so it was serving the files as it should. The problem was I still had a blank page staring at me, nothing at all was displayed.&lt;/p&gt;

&lt;p&gt;By this time, I had already spent a couple of hours making pointless changes, debugging, bundling in different ways (with no cache access, without optimizations, etc) and reading tons of docs, Stack Overflow posts and GitHub issues. I took a little rest and came back to it. I kept investigating and found these two posts that gave me the key of what was happening:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://medium.com/swlh/building-a-static-single-page-application-with-javascript-for-github-pages-and-more-eb568b436bea#8f76"&gt;Building a Static Single Page Application with JavaScript, for GitHub pages and more …&lt;/a&gt; written by Weiyuan.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://itnext.io/so-you-want-to-host-your-single-age-react-app-on-github-pages-a826ab01e48"&gt;So you want to host your Single Page React App on GitHub Pages?&lt;/a&gt; written by Brendan McIlhenny.&lt;/p&gt;

&lt;p&gt;And the key was that besides the general routing of the application, I had also used the React components &lt;code&gt;BrowserRouter&lt;/code&gt;, &lt;code&gt;Route&lt;/code&gt; and &lt;code&gt;Link&lt;/code&gt;, so it appeared that the breaking point could have been there. Spoiler alert: it was.&lt;/p&gt;

&lt;p&gt;So I fixed the routes and prepended a &lt;code&gt;/Portfolio_like_project&lt;/code&gt; to the destiny routes of Routes and Links, deployed it and it worked! I was happy that it was finally live and I managed to find the ways things work. &lt;/p&gt;

&lt;p&gt;Until, I run the dev local server and it crashed, which was logical because it couldn't find the files and routes pointed by the new location I prepended before. I tried a couple of workarounds and settled with the next solution:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I created a &lt;code&gt;.env&lt;/code&gt; file which contained the relative path I wanted to add:
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;BASE_RELATIVE_PATH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;/Portfolio_like_project&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;ul&gt;
&lt;li&gt;I created a new js file which was in charge of detecting if I was in production mode and at the same time not in localhost, the code looks like this:
&lt;/li&gt;
&lt;/ul&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;isEnvProduction&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;NODE_ENV&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;production&lt;/span&gt;&lt;span class="dl"&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;isEnvNotLocalhost&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;hostname&lt;/span&gt; &lt;span class="o"&gt;!==&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;localhost&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;window&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;location&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;href&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;127.0.0.1&lt;/span&gt;&lt;span class="dl"&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;baseRelativePath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;isEnvProduction&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nx"&gt;isEnvNotLocalhost&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;BASE_RELATIVE_PATH&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="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;baseRelativePath&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;A little note here: Parcel sets the NODE_ENV variable to 'production' or 'development' depending on the build (if it's been built and bundled, or if it's running on the dev server, respectively). So I took advantage of that. If I was in a production environment I prepended the relative path and if I wasn't I prepended an empty string.&lt;br&gt;
Then all I had to do was use this basePath before every redirection, like this:&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="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;baseRelativePath&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;path.js&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Link&lt;/span&gt; &lt;span class="nx"&gt;to&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseRelativePath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&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="nx"&gt;Home&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/Link&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;Route&lt;/span&gt; &lt;span class="nx"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;baseRelativePath&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/`&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="nx"&gt;element&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="cm"&gt;/*some element*/&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="sr"&gt;/&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After making that change I managed to make the app work in a local development, local production and remote production environment. Success!&lt;/p&gt;

&lt;p&gt;It is not the most elegant solution though, making a template literal for every path in order to prepend this basePath sounds like something that could be solved in other way. As a React beginner I find it good enough for the moment, and I hope I can find a better way of doing this, if I do I will be pasting a link for the update here. As for now, it is staying like this.&lt;/p&gt;

&lt;p&gt;Thanks for reading! And if you came here and I managed to help you, I'm glad I could serve you useful 😊.&lt;/p&gt;

</description>
      <category>react</category>
      <category>parcel</category>
      <category>github</category>
      <category>deployment</category>
    </item>
  </channel>
</rss>
