<?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: Reece Daniels</title>
    <description>The latest articles on DEV Community by Reece Daniels (@rubengmurray).</description>
    <link>https://dev.to/rubengmurray</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%2F382048%2Fba360f4e-4927-45a8-97fb-088323b8894a.jpeg</url>
      <title>DEV Community: Reece Daniels</title>
      <link>https://dev.to/rubengmurray</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rubengmurray"/>
    <language>en</language>
    <item>
      <title>app.cacher.io</title>
      <dc:creator>Reece Daniels</dc:creator>
      <pubDate>Thu, 28 Mar 2024 21:35:29 +0000</pubDate>
      <link>https://dev.to/rubengmurray/appcacherio-83k</link>
      <guid>https://dev.to/rubengmurray/appcacherio-83k</guid>
      <description>&lt;p&gt;I'm a big fan of this app.&lt;/p&gt;

&lt;p&gt;Whilst Copilot (another great app) is there to help predict what you might want to write, app.cacher.io is there to help you remember the things you've done before.&lt;/p&gt;

&lt;p&gt;It's got a great VSCode extension that let's you search for existing snippets at the drop of a hat and also allows you to save new snippets directly from VSCode.&lt;/p&gt;

&lt;p&gt;Well worth the $6 per month.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Why Your npm link Commands Might Be Failing</title>
      <dc:creator>Reece Daniels</dc:creator>
      <pubDate>Tue, 31 Mar 2020 11:43:00 +0000</pubDate>
      <link>https://dev.to/rubengmurray/why-your-npm-link-commands-might-be-failing-4ncj</link>
      <guid>https://dev.to/rubengmurray/why-your-npm-link-commands-might-be-failing-4ncj</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%2Frubensbits.co%2Fmedia%2Fnpm.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%2Frubensbits.co%2Fmedia%2Fnpm.png" alt="npm"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Problem
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;When you try to use &lt;code&gt;npm link&lt;/code&gt; to install a dependency you’re working on locally, the changes aren’t reflected in your project.&lt;/p&gt;

&lt;p&gt;You also see intermittent issues starting your project (esp. in TypeScript), as well as subdependencies not resolving correctly.&lt;/p&gt;

&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;There are two issues you can run into when &lt;code&gt;npm link&lt;/code&gt; isn’t working which are worth noting;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;nvm related issues&lt;/li&gt;
&lt;li&gt;Peer Dependency related issues&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  nvm
&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;nvm&lt;/code&gt;, or Node Version Manager, is a tool used to run different versions of node locally across microservices at the same time.&lt;/p&gt;

&lt;p&gt;When running &lt;code&gt;npm link&lt;/code&gt;, the specific version of node being used in the project will be used to create the link, which means only projects using the same version of node will be able to access the local version of the dependency. This can be all the more frustrating because npm link doesn’t throw an error when this happens.&lt;/p&gt;

&lt;p&gt;Here’s the readout when using different versions of node (one using &lt;code&gt;8.9.4&lt;/code&gt;, the other using &lt;code&gt;12.13.1&lt;/code&gt;):&lt;/p&gt;

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

/Users/myName/dev/_github/myRepo/node_modules/myDependency -&amp;gt;
/Users/myName/.nvm/versions/node/v12.13.1/lib/node_modules/myDependency


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

&lt;/div&gt;

&lt;p&gt;And here’s the readout with the same version of node (both using &lt;code&gt;8.9.4&lt;/code&gt;):&lt;/p&gt;

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

/Users/myName/dev/_github/myRepo/node_modules/myDependency -&amp;gt;
/Users/myName/.nvm/versions/node/v8.9.4/lib/node_modules/myDependency -&amp;gt;
/Users/myName/dev/_github/myDependency


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

&lt;/div&gt;

&lt;p&gt;Notice how the bottom line resolves to a folder where the dependency resides locally.&lt;/p&gt;

&lt;p&gt;To fix this, use &lt;code&gt;node -v&lt;/code&gt; in each project and check the running version of node. Use &lt;code&gt;nvm install x.x.x&lt;/code&gt; &amp;amp; &lt;code&gt;nvm use x.x.x&lt;/code&gt; to match them up.&lt;/p&gt;

&lt;p&gt;Afterward, delete your &lt;code&gt;node_modules&lt;/code&gt;, delete your &lt;code&gt;package-lock.json&lt;/code&gt;, re-run &lt;code&gt;npm i&lt;/code&gt;, and re-run &lt;code&gt;npm link&lt;/code&gt; in your dependency folder and &lt;code&gt;npm link myDependency&lt;/code&gt; in your project folder.&lt;/p&gt;

&lt;p&gt;That should help.&lt;/p&gt;

&lt;h4&gt;
  
  
  Peer Dependencies
&lt;/h4&gt;

&lt;p&gt;If your dependency has references to &lt;code&gt;peerDependencies&lt;/code&gt; in it’s &lt;code&gt;package.json&lt;/code&gt; you could stumble into issues with symlinks. These manifest themselves in the form of the peerDependency being unablee to be resolved at either compile time or at run time when needed.&lt;/p&gt;

&lt;p&gt;The fix for this relatively simple. Add &lt;code&gt;--preserve-symlinks&lt;/code&gt; into your start script e.g. &lt;code&gt;node --preserve-symlinks build&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This will instruct your startup script to look in the correct place for it’s peer dependencies when running locally. Note that you’ll want to remove the flag once you’re done testing locally.&lt;/p&gt;




&lt;h1&gt;
  
  
  Problem (Hopefully) Solved
&lt;/h1&gt;

&lt;p&gt;If you have any questions you’d like to ask me about this post, feel free to reach me on &lt;a href="https://twitter.com/rubengmurray" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/rubengmurray" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>npm</category>
      <category>nvm</category>
    </item>
    <item>
      <title>Creating Interfaces From Joi Schemas In TypeScript</title>
      <dc:creator>Reece Daniels</dc:creator>
      <pubDate>Sat, 14 Mar 2020 11:43:00 +0000</pubDate>
      <link>https://dev.to/rubengmurray/creating-interfaces-from-joi-schemas-in-typescript-35ab</link>
      <guid>https://dev.to/rubengmurray/creating-interfaces-from-joi-schemas-in-typescript-35ab</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%2Frubensbits.co%2Fmedia%2Fthumb.webp" 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%2Frubensbits.co%2Fmedia%2Fthumb.webp" alt="Thumbs Up Image"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Problem
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Using &lt;a href="https://hapi.dev/module/joi/" rel="noopener noreferrer"&gt;joi&lt;/a&gt; inside a Typescript project means you need to create two validation schemas, one for Joi at runtime and one for Typescript at compile time.&lt;/p&gt;

&lt;p&gt;This causes you issues with maintainability, consistency, and violates the DRY principle.&lt;/p&gt;

&lt;h3&gt;
  
  
  Code Example
&lt;/h3&gt;

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

import * as joi from '@hapi/joi';

// Ignore the technical arguments of these schemas - purely for example purposes
interface UserAddress = {
  // etc..
  postCode: string;
  startDate: string;
  endDate: string;
}

interface User = {
  name: string;
  phoneNumber?: number;
  addresses: UserAddress[]
}

const userAddress = joi.object({
  // etc...
  postCode: joi.string().required()
  startDate: joi.date().required(),
  endDate: joi.date().required()
})

const user = joi.object(({
  name: joi.string().required(),
  phoneNumber: joi.number().optional(),
  addresses: joi.array().items(userAddress).required(),
}))


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

&lt;/div&gt;




&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;Use &lt;a href="https://www.npmjs.com/package/joi-extract-type" rel="noopener noreferrer"&gt;joi-extract-type.&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;An NPM package that is surprisingly underused (currently only 4,300 downloads per week on NPM) give it’s support for complex joi schemas.&lt;/p&gt;

&lt;p&gt;There are two issues that should be noted as of writing this; one technical, one aesthetic&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;It has trouble managing the &lt;code&gt;.unknown&lt;/code&gt; joi method at the object level (&lt;a href="https://github.com/hapijs/joi/blob/v8.0.3/API.md#objectunknownallow" rel="noopener noreferrer"&gt;which declares that unknown keys are allowed on an object&lt;/a&gt;). Looking through the joi-extract-type code, it appears the method isn’t catered for.&lt;/li&gt;
&lt;li&gt;You lose the pretty TypeScript interface look and feel - with a lot of your code now rendered in the standard JavaScript object colouring (theme dependant of course).&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Code Example
&lt;/h3&gt;

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

import * as joi from '@hapi/joi';
import 'joi-extract-type'

const userAddress = joi.object({
  // etc...
  postCode: joi.string().required()
  startDate: joi.date().required(),
  endDate: joi.date().required()
})

const user = joi.object(({
  name: joi.string().required(),
  phoneNumber: joi.number().optional(),
  addresses: joi.array().items(userAddress).required(),
}))

export type User = joi.extractType&amp;lt;typeof user&amp;gt;;
export type UserAddress = joi.extractType&amp;lt;typeof userAddress&amp;gt;;


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

&lt;/div&gt;

&lt;p&gt;User &amp;amp; UserAddress will work equivalent to traditionally declared User &amp;amp; UserAddress interfaces.&lt;/p&gt;

&lt;p&gt;You’ll also need to make sure the version of &lt;code&gt;joi-extract-type&lt;/code&gt; that’s being used is aligned with the correct version of &lt;code&gt;joi&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@hapi/joi@17&lt;/code&gt; &amp;amp; &lt;code&gt;joi-extract-type@15.0.2&lt;/code&gt; seem to work fine together.&lt;/p&gt;




&lt;h1&gt;
  
  
  Problem Solved
&lt;/h1&gt;

&lt;p&gt;If you have any questions you’d like to ask me about this post, feel free to reach me on &lt;a href="https://twitter.com/rubengmurray" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or &lt;a href="https://github.com/rubengmurray" rel="noopener noreferrer"&gt;Github&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>joi</category>
      <category>typescript</category>
      <category>dry</category>
      <category>validation</category>
    </item>
    <item>
      <title>Using Cookies, Puppeteer &amp; NodeJS To Mirror A Chrome Profile on macOS</title>
      <dc:creator>Reece Daniels</dc:creator>
      <pubDate>Mon, 10 Jun 2019 10:00:00 +0000</pubDate>
      <link>https://dev.to/rubengmurray/using-cookies-puppeteer-nodejs-to-mirror-a-chrome-profile-on-macos-1l6m</link>
      <guid>https://dev.to/rubengmurray/using-cookies-puppeteer-nodejs-to-mirror-a-chrome-profile-on-macos-1l6m</guid>
      <description>

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JZ0rs23q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://rubensbits.co/media/puppeteer.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JZ0rs23q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://rubensbits.co/media/puppeteer.png" alt="Puppeteer!" width="290" height="422"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Mirroring the state of one of your existing Chrome Profiles in Puppeteer can prove extremely useful for local projects and testing.&lt;/p&gt;

&lt;p&gt;Unless you’re interested in simulating an entire login process, utilising pre-existing settings - in this case, cookies - can significantly reduce your time spent replicating a state that exists elsewhere on your machine.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;The following process requires &lt;a href="https://nodejs.org/en/download/"&gt;NodeJS&lt;/a&gt;, &lt;a href="https://docs.npmjs.com/downloading-and-installing-node-js-and-npm"&gt;NPM&lt;/a&gt; and &lt;a href="https://pptr.dev/"&gt;Puppeteer&lt;/a&gt;. You’ll need to install all of those items in that order before going any further. Follow the instructions on their respective websites to get them installed on your system&lt;/em&gt;&lt;/p&gt;




&lt;p&gt;The first issue is accessing the cookies. Cookies are encrypted for good reason: they contain sensitive information. On macOS, they’re ‘signed’ with a Chrome encryption key into an SQLite database which is managed by the OS keychain. In order to decrypt the signed cookies, your Node application must have access to the Chrome key inside the keychain. This requires authorisation by the logged in macOS user.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--aosm7GQQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/./../../media/csn1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--aosm7GQQ--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/./../../media/csn1.png" alt="Node-Auth" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Thankfully, there is an NPM module &lt;a href="https://github.com/bertrandom/chrome-cookies-secure"&gt;&lt;code&gt;chrome-cookies-secure&lt;/code&gt;&lt;/a&gt; that is setup to handle this process. Copy and run the following code in your terminal (in the root of your project directory) to add the &lt;code&gt;chrome-cookies-secure&lt;/code&gt; module to your project:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;npm i --save chrome-cookies-secure
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;If you’re not prompted to authorise Node access to your keychain on the module install, don’t worry. You will be prompted when you run the basic NodeJS app described a little further down.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Next you’ll need to identify the path to the Chrome Profile you want to mirror (you may have multiple you’d like to choose from).&lt;/p&gt;

&lt;p&gt;Open Chrome and make sure you’re browsing with the profile you want to retrieve the cookies for, and navigate to &lt;code&gt;chrome://version&lt;/code&gt;. You’ll find the Profile of the current browser session under &lt;code&gt;Profile Path&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--JRsL-xSu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/./../../media/cpp1.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--JRsL-xSu--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/./../../media/cpp1.jpg" alt="Chrome-Profile" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;You can view all of your Chrome Profile directories at &lt;code&gt;Users/yourName/Library/Application Support/Google/Chrome&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is often written as &lt;code&gt;~/Library/Application Support/Google/Chrome&lt;/code&gt; where &lt;code&gt;~&lt;/code&gt; refers to the user’s root directory (In Finder &lt;code&gt;Macintosh HD &amp;gt; Users &amp;gt; userName&lt;/code&gt; = &lt;code&gt;~&lt;/code&gt;).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Now you have the basic information you need to retrieve your cookies within your Node app! Below is a simple code snippet to demonstrate the functionality. Let’s take a look at our &lt;code&gt;https://www.google.com&lt;/code&gt; cookies.&lt;/p&gt;

&lt;p&gt;In a file of your choosing inside your project folder (I’ve called mine &lt;code&gt;server.js&lt;/code&gt;) paste in the following code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const chrome = require('chrome-cookies-secure');

const url = 'https://www.google.com';

chrome.getCookies(url, 'puppeteer', function(err, cookies) {
    if (err) {
        console.log(err, 'error');
        return
    }
    // do stuff here...
    console.log(cookies, 'cookies');
}, 'yourProfile') // e.g. 'Profile 2'
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;The module does not yet fully support Promises or async/await, but we’re looking to add support. You can help us add it in at &lt;code&gt;https://github.com/bertrandom/chrome-cookies-secure&lt;/code&gt;Update! March 2020 - there is a PR for a Promise wrapper awaiting approval - &lt;a href="https://github.com/bertrandom/chrome-cookies-secure/pull/21"&gt;https://github.com/bertrandom/chrome-cookies-secure/pull/21&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--0Xk3zEV9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/./../../media/gyc1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--0Xk3zEV9--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/./../../media/gyc1.png" alt="Get-Your-Cookies" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Next, ensuring you’re in the project root directory in your terminal, run &lt;code&gt;node yourfilename.js&lt;/code&gt;. You should see the cookies for the given profile and url you have chosen appear right there in the terminal, e.g:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--NvtVjDUa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/./../../media/gyc2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--NvtVjDUa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/v1/./../../media/gyc2.png" alt="Cookie-Output" width="" height=""&gt;&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;In this example, we are looking at Google’s cookies. In the next section you will want to change this to a website where you are currently logged in&lt;/p&gt;
&lt;/blockquote&gt;




&lt;p&gt;Now you can see your cookies in NodeJS, you can load them into Puppeteer!&lt;/p&gt;

&lt;p&gt;Update your code to the following and run &lt;code&gt;node yourfilename.js&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;const chrome = require('chrome-cookies-secure');
const puppeteer = require('puppeteer');

const url = 'https://www.yoururl.com';

const getCookies = (callback) =&amp;gt; {
    chrome.getCookies(url, 'puppeteer', function(err, cookies) {
        if (err) {
            console.log(err, 'error');
            return
        }
        console.log(cookies, 'cookies');
        callback(cookies);
    }, 'yourProfile') // e.g. 'Profile 2'
}

getCookies(async (cookies) =&amp;gt; {
    const browser = await puppeteer.launch({
        headless: false
    });
    const page = await browser.newPage();

    await page.setCookie(...cookies);
    await page.goto(url);
    await page.waitFor(1000);
    browser.close()
});
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You’ll see Puppeteer open and navigate to your chosen site, and hopefully, providing there are no further security measures such as 2FA, you’ll see that you are logged in!&lt;/p&gt;

&lt;p&gt;It’s worth noting there can be a thirty minute delay between new cookies in your Chrome Profile being reflected on your hard-drive (thus being accessible in your Node app). This is because Chrome persists cookies to storage once every thirty minutes. So if you have new cookies, give it 30 minutes and check it again.&lt;/p&gt;

&lt;p&gt;You’ll also need to fully qualify URLs in order to retrieve all possible cookies for a given site i.e &lt;code&gt;https://www.google.com&lt;/code&gt; not &lt;code&gt;https://google.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But that’s it!&lt;/p&gt;

&lt;p&gt;You should now be able to do what you want to do with Puppeteer, utilising a login state, preferences, or whatever else, from one of your Chrome Profiles!&lt;/p&gt;

</description>
      <category>puppeteer</category>
      <category>chrome</category>
      <category>cookies</category>
    </item>
    <item>
      <title>GoDaddy, Surge, Apex Domains &amp; CNAME Records</title>
      <dc:creator>Reece Daniels</dc:creator>
      <pubDate>Tue, 28 May 2019 10:00:00 +0000</pubDate>
      <link>https://dev.to/rubengmurray/godaddy-apex-domains-cname-records-3dk5</link>
      <guid>https://dev.to/rubengmurray/godaddy-apex-domains-cname-records-3dk5</guid>
      <description>

&lt;h1&gt;
  
  
  Problem
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Summary
&lt;/h3&gt;

&lt;p&gt;You need to get an apex domain (&lt;a href="https://yoursite.com"&gt;https://yoursite.com&lt;/a&gt;) you purchased at GoDaddy resolving correctly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;p&gt;The problem you face if your asked to do this is that - for basic domain purchases at least - GoDaddy doesn’t let you add &lt;code&gt;CNAME&lt;/code&gt; records for apex domains .&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;An apex domain refers to &lt;a href="https://yoursite.com"&gt;https://yoursite.com&lt;/a&gt; rather than &lt;a href="https://www.yoursite.com"&gt;https://www.yoursite.com&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Solution
&lt;/h1&gt;

&lt;h3&gt;
  
  
  Explanation
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;The advice from GoDaddy is that you must delete all &lt;code&gt;A&lt;/code&gt; &amp;amp; &lt;code&gt;CNAME&lt;/code&gt; records on GoDaddy first before adding any other &lt;code&gt;CNAME&lt;/code&gt; or &lt;code&gt;A&lt;/code&gt; records.&lt;/li&gt;
&lt;li&gt;You must replace the &lt;code&gt;CNAME&lt;/code&gt; &lt;code&gt;@&lt;/code&gt; record with an &lt;code&gt;A&lt;/code&gt; &lt;code&gt;@&lt;/code&gt; record using the IP of your host provider.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;My host is surge.sh, who provide their IP in &lt;a href="https://surge.sh/help/adding-a-custom-domain"&gt;this documentation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Thus, to have my domain recognised when deploying to surge I needed to delete all existing &lt;code&gt;A&lt;/code&gt; &amp;amp; &lt;code&gt;CNAME&lt;/code&gt; records, and to add the following two records following in the &lt;code&gt;Type&lt;/code&gt; : &lt;code&gt;Name&lt;/code&gt; : &lt;code&gt;Value&lt;/code&gt; format:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;CNAME&lt;/code&gt;: &lt;code&gt;www&lt;/code&gt; : &lt;code&gt;na-west1.surge.sh&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;code&gt;A&lt;/code&gt; : &lt;code&gt;@&lt;/code&gt; : &lt;code&gt;45.55.110.124&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once complete, my domain resolved within 5 minutes.&lt;/p&gt;

&lt;p&gt;If you’re struggling to locate your providers IP, try messaging them on Twitter or searching StackOverflow, but once you have it, it should do the trick.&lt;/p&gt;

&lt;p&gt;Original source: &lt;a href="https://www.godaddy.com/community/Managing-Domains/domain-DNS-with-surge-sh/td-p/24075"&gt;GoDaddy Forums&lt;/a&gt;&lt;/p&gt;

</description>
      <category>dns</category>
      <category>cname</category>
      <category>godaddy</category>
      <category>surge</category>
    </item>
  </channel>
</rss>
