<?xml version="1.0" encoding="utf-8"?><?xml-stylesheet type="text/css" href="https://www.aaron-gustafson.com/c/feed.min.css" ?><feed xmlns="http://www.w3.org/2005/Atom"
      xmlns:amg="https://www.aaron-gustafson.com.com/amg-dtd/"><title>Aaron Gustafson: Content tagged URLs</title><subtitle>The latest 20 posts and links tagged URLs.</subtitle><id>https://www.aaron-gustafson.com</id><link href="https://www.aaron-gustafson.com/feeds/urls.xml" rel="self"/><link href="https://www.aaron-gustafson.com"/><author><name>Aaron Gustafson</name><uri>https://www.aaron-gustafson.com</uri></author><updated>2024-05-24T16:23:56Z</updated><entry><id>https://www.aaron-gustafson.com/notebook/links/link-rot-and-digital-decay-on-government-news-and-other-webpages/</id><title type="html"><![CDATA[🔗 Link Rot and Digital Decay on Government, News and Other Webpages]]></title><link href="https://www.aaron-gustafson.com/notebook/links/link-rot-and-digital-decay-on-government-news-and-other-webpages/" rel="alternate" type="text/html" /><link href="https://www.pewresearch.org/data-labs/2024/05/17/when-online-content-disappears/" rel="related" type="text/html" /><published>2024-05-24T16:23:56Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<blockquote><p>A quarter of all webpages that existed at one point between 2013 and 2023 are no longer accessible, as of October 2023. In most cases, this is because an individual page was deleted or removed on an otherwise functional website.</p></blockquote><p>Linkrot, especially in government and legal scenarios, is a tremendous problem, which is why we need services like the Internet Archive and <a href="http://Perma.cc">Perma.cc</a>. If you have the means, please consider supporting these, and similar, projects!</p>]]></content><amg:twitter><![CDATA[Linkrot, especially in government and legal scenarios, is a tremendous problem, which is why we need services like the @InternetArchive and @PermaCC.]]></amg:twitter><category term="the web" /><category term="industry" /><category term="URLs" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/salvaging-linkrot-with-the-wayback-machine/</id><title type="html"><![CDATA[✍🏻 Salvaging linkrot with the Wayback Machine]]></title><link href="https://www.aaron-gustafson.com/notebook/salvaging-linkrot-with-the-wayback-machine/" rel="alternate" type="text/html" /><published>2022-08-31T21:37:31Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>While making some updates to the site, I did a 404 scan of <a href="/notebook/links/">my link blog</a> and the results were… less than awesome. So I decided to work some Eleventy magic to recover from them.</p><h2 id="step-1%3A-log-the-404s-to-a-file" tabindex="-1"><a class="header-anchor" href="#step-1%3A-log-the-404s-to-a-file" aria-hidden="true">#</a> Step 1: Log the 404s to a file</h2><p>I make ample use of <a href="https://www.11ty.dev/docs/data-global/">Eleventy’s global data files</a>, but 404s didn’t feel like something I needed to have as part of the data cascade. Instead, I’m logging them to a YAML file in my <code>./_cache</code> folder. For simplicity, they get logged like this:</p><pre class="language-yml" tabindex="0"><code class="language-yml"><span class="token key atrule"><a href="https://path.to/original/page/that-is-404ing/">https://path.to/original/page/that-is-404ing/</a></span><span class="token punctuation">:</span><span class="token boolean important">true</span></code></pre><p>I chose YAML as it’s about as bare-bones as you can get when it comes to file formats and is pretty easy to work with in the context of Eleventy.</p><h2 id="step-2%3A-add-an-eleventy-data-file-to-my-links-folder" tabindex="-1"><a class="header-anchor" href="#step-2%3A-add-an-eleventy-data-file-to-my-links-folder" aria-hidden="true">#</a> Step 2: Add an Eleventy data file to my links folder</h2><p>If you’re not familiar, Eleventy allows you to create <a href="https://www.11ty.dev/docs/data-template-dir/">directory-level data files</a> that can be used to augment file-level data. I was originally using it to define the <var>layout</var> and <var>permalink</var> front matter variables for all the links using the JSON option, but <a href="https://www.11ty.dev/docs/data-js/">as a JavaScript file, directory-level data becomes even more powerful</a>.</p><p>Setting up your data file is relatively straightforward using <code>module.exports</code>:</p><pre class="language-js" tabindex="0"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span><span class="token punctuation">{</span><span class="token literal-property property">layout</span><span class="token operator">:</span><span class="token string">“layouts/link.njk”</span><span class="token punctuation">,</span><span class="token literal-property property">permalink</span><span class="token operator">:</span><span class="token string">“/notebook/{{ page.filePathStem }}/”</span><span class="token punctuation">,</span><span class="token literal-property property">eleventyComputed</span><span class="token operator">:</span><span class="token punctuation">{</span><span class="token function-variable function">custom_property</span><span class="token operator">:</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span><span class="token keyword">return</span> some_value_based_on_data<span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><p>Here I’m defining two static values (<var>layout</var> and <var>permalink</var>) and a computed value (the hypothetical <var>custom_property</var>).</p><h2 id="step-3%3A-consult-the-404-log" tabindex="-1"><a class="header-anchor" href="#step-3%3A-consult-the-404-log" aria-hidden="true">#</a> Step 3: Consult the 404 log</h2><p>As I mentioned, the 404 logging happens separately and results in updates to <code>_cache/404.yml</code>. To make use of all this in the Eleventy data file, I need to set up a few things at the top of the file:</p><pre class="language-js" tabindex="0"><code class="language-js"><span class="token keyword">const</span> fs <span class="token operator">=</span><span class="token function">require</span><span class="token punctuation">(</span><span class="token string">“fs”</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">const</span> yaml <span class="token operator">=</span><span class="token function">require</span><span class="token punctuation">(</span><span class="token string">“js-yaml”</span><span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">const</span> cached404s <span class="token operator">=</span> yaml<span class="token punctuation">.</span><span class="token function">load</span><span class="token punctuation">(</span>fs<span class="token punctuation">.</span><span class="token function">readFileSync</span><span class="token punctuation">(</span><span class="token string">“_cache/404s.yml”</span><span class="token punctuation">)</span><span class="token punctuation">)</span><span class="token punctuation">;</span></code></pre><p>Here I’m bringing in Node’s File System and <a href="https://www.npmjs.com/package/js-yaml">JS-YAML</a>. Then I am loading the YAML file into memory as <var>cached404s</var>, leveraging those utilities.</p><p>Next up is defining a helper function to search <var>cached404s</var> for a match:</p><pre class="language-js" tabindex="0"><code class="language-js"><span class="token keyword">function</span><span class="token function">is404ing</span><span class="token punctuation">(</span><span class="token parameter">url</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">return</span> url <span class="token keyword">in</span> cached404s<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>This function takes the URL as an argument and returns <code>true</code> or <code>false</code>. Making use of this in the <code>eleventyComputed</code> section is straightforward:</p><pre class="language-js" tabindex="0"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span><span class="token punctuation">{</span><span class="token literal-property property">layout</span><span class="token operator">:</span><span class="token string">“layouts/link.njk”</span><span class="token punctuation">,</span><span class="token literal-property property">permalink</span><span class="token operator">:</span><span class="token string">“/notebook/{{ page.filePathStem }}/”</span><span class="token punctuation">,</span><span class="token literal-property property">eleventyComputed</span><span class="token operator">:</span><span class="token punctuation">{</span><span class="token function-variable function">is_404</span><span class="token operator">:</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span><span class="token keyword">return</span><span class="token function">is404ing</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>ref_url<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><p>In my case, <var>ref_url</var> is the front matter field storing the URL I’m linking to from my link blog, so I return the value of passing that to <code>is404ing()</code> as <var>is_404</var>.</p><h2 id="step-4%3A-lean-on-the-wayback-machine" tabindex="-1"><a class="header-anchor" href="#step-4%3A-lean-on-the-wayback-machine" aria-hidden="true">#</a> Step 4: Lean on the Wayback Machine</h2><p>The next thing I want to do is generate a link that has a good chance of working for my readers. Thankfully the <a href="https://web.archive.org/">Wayback Machine</a> has a predictable URL structure for entries and it’s pretty good about handgun redirects to the most temporally-proximate snapshot when you give it a date to work from. Knowing that, I set up another helper function:</p><pre class="language-js" tabindex="0"><code class="language-js"><span class="token keyword">function</span><span class="token function">archived</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span><span class="token punctuation">{</span><span class="token keyword">let</span> archive_url <span class="token operator">=</span><span class="token string">“<a href="https://web.archive.org/web/">https://web.archive.org/web/</a>{{ DATE }}/{{ URL }}”</span><span class="token punctuation">;</span><span class="token keyword">let</span> month <span class="token operator">=</span> data<span class="token punctuation">.</span>date<span class="token punctuation">.</span><span class="token function">getUTCMonth</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token operator">+</span><span class="token number">1</span><span class="token punctuation">;</span>month <span class="token operator">=</span> month <span class="token operator">&lt;</span><span class="token number">10</span><span class="token operator">?</span><span class="token string">“0”</span><span class="token operator">+</span> month <span class="token operator">:</span> month<span class="token punctuation">;</span><span class="token keyword">let</span> day <span class="token operator">=</span> data<span class="token punctuation">.</span>date<span class="token punctuation">.</span><span class="token function">getDay</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>day <span class="token operator">=</span> day <span class="token operator">&lt;</span><span class="token number">10</span><span class="token operator">?</span><span class="token string">“0”</span><span class="token operator">+</span> day <span class="token operator">:</span> day<span class="token punctuation">;</span>archive_url <span class="token operator">=</span> archive_url<span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">“{{ DATE }}”</span><span class="token punctuation">,</span><span class="token template-string"><span class="token template-punctuation string"><code>&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;data&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;date&lt;span class=&quot;token punctuation&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;token function&quot;&gt;getUTCFullYear&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;token punctuation&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;month&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token interpolation&quot;&gt;&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;${&lt;/span&gt;day&lt;span class=&quot;token interpolation-punctuation punctuation&quot;&gt;}&lt;/span&gt;&lt;/span&gt;&lt;span class=&quot;token template-punctuation string&quot;&gt;</code></span></span><span class="token punctuation">)</span><span class="token punctuation">.</span><span class="token function">replace</span><span class="token punctuation">(</span><span class="token string">“{{ URL }}”</span><span class="token punctuation">,</span> data<span class="token punctuation">.</span>ref_url<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token keyword">return</span> archive_url<span class="token punctuation">;</span><span class="token punctuation">}</span></code></pre><p>Note: I know this isn’t the most elegant/efficient code, I wanted to show step-by-step what’s happening here.</p><p>This function takes the <var>data</var> object as an argument and composes a URL that points to a snapshot of the given page (<var>data.ref_url</var>) at the time I saved the link (<var>data.date</var>). The <var>data.date</var> value is already a JavaScript date, so it’s pretty easy to turn it into the format the Wayback Machine expects (YYYYMMDD). In the end, this method returns a URL that looks something like this:</p><blockquote><p><a href="https://web.archive.org/web/20150102/http://andregarzia.com/posts/en/whatsappdoesntunderstandtheweb/">https://web.archive.org/web/20150102/http://andregarzia.com/posts/en/whatsappdoesntunderstandtheweb/</a></p></blockquote><p>With that helper in place, I can make use of it within <code>eleventyComputed</code>:</p><pre class="language-js" tabindex="0"><code class="language-js">module<span class="token punctuation">.</span>exports <span class="token operator">=</span><span class="token punctuation">{</span><span class="token literal-property property">layout</span><span class="token operator">:</span><span class="token string">“layouts/link.njk”</span><span class="token punctuation">,</span><span class="token literal-property property">permalink</span><span class="token operator">:</span><span class="token string">“/notebook/{{ page.filePathStem }}/”</span><span class="token punctuation">,</span><span class="token literal-property property">eleventyComputed</span><span class="token operator">:</span><span class="token punctuation">{</span><span class="token function-variable function">is_404</span><span class="token operator">:</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span><span class="token keyword">return</span><span class="token function">is404ing</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>ref_url<span class="token punctuation">)</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token function-variable function">archived</span><span class="token operator">:</span><span class="token punctuation">(</span><span class="token parameter">data</span><span class="token punctuation">)</span><span class="token operator">=&gt;</span><span class="token punctuation">{</span><span class="token keyword">return</span><span class="token function">is404ing</span><span class="token punctuation">(</span>data<span class="token punctuation">.</span>ref_url<span class="token punctuation">)</span><span class="token operator">?</span><span class="token function">archived</span><span class="token punctuation">(</span>data<span class="token punctuation">)</span><span class="token operator">:</span><span class="token boolean">false</span><span class="token punctuation">;</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">}</span><span class="token punctuation">,</span><span class="token punctuation">}</span><span class="token punctuation">;</span></code></pre><p>Now every link in my link blog will have an <var>is_404</var> value that is <code>true</code> or <code>false</code> and an <var>archived</var> value that is either a valid Wayback Machine URL (if the page is 404-ing) or <code>false</code>.</p><h2 id="step-5%3A-using-these-in-the-my-template" tabindex="-1"><a class="header-anchor" href="#step-5%3A-using-these-in-the-my-template" aria-hidden="true">#</a> Step 5: Using these in the my template</h2><p>I use Nunjucks for most of my site’s templating, but you can make use of these computed properties in any supporting templating language. Knowing if a linked URL is 404-ing allows me to</p><ul><li>display the title without a link,</li><li>display the source without a link, and</li><li>provide additional copy about the link’s 404 status and provide the Wayback Machine link instead.</li></ul><p>I am only going to share code with you for that final bit as it should give you enough of a sense of how you can use these properties in the other contexts too.</p><pre class="language-liquid" tabindex="0"><code class="language-liquid"><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span><span class="token keyword">if</span> is_404 <span class="token delimiter punctuation">%}</span></span><span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>p</span><span class="token punctuation">&gt;</span></span>This link is 404-ing<span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span><span class="token keyword">if</span> archived <span class="token delimiter punctuation">%}</span></span>, but<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;</span>a</span><span class="token attr-name">rel</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span>bookmark<span class="token punctuation">”</span></span><span class="token attr-name">href</span><span class="token attr-value"><span class="token punctuation attr-equals">=</span><span class="token punctuation">“</span><span class="token liquid language-liquid"><span class="token delimiter punctuation">{{</span> archived <span class="token delimiter punctuation">}}</span></span><span class="token punctuation">”</span></span><span class="token punctuation">&gt;</span></span>you can view anarchived version on the Wayback Machine<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>a</span><span class="token punctuation">&gt;</span></span><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span><span class="token keyword">endif</span><span class="token delimiter punctuation">%}</span></span>.<span class="token tag"><span class="token tag"><span class="token punctuation">&lt;/</span>p</span><span class="token punctuation">&gt;</span></span><span class="token liquid language-liquid"><span class="token delimiter punctuation">{%</span><span class="token keyword">endif</span><span class="token delimiter punctuation">%}</span></span></code></pre><p>Here you can see I am injecting a <code>footer</code> into the markup when the entry is 404-ing. Within that footer, I note the link’s status. Then I inject some additional text to point to the Wayback Machine’s archive of the page. It’s worth noting that I am being overly cautious here and only injecting the link if <var>post.data.archived</var> is truthy. This will ensure that the link won’t be shown if something fails in my code or I change how I am implementing the <var>archived</var> property.</p><h2 id="crossing-my-fingers" tabindex="-1"><a class="header-anchor" href="#crossing-my-fingers" aria-hidden="true">#</a> Crossing my fingers</h2><p>Relying on an unverified URL, even one at the Wayback Machine, is risky, but so far this approach seems to be working. If you’ve got a link blog suffering from link rot, you might consider setting up something similar. Hopefully this will help jumpstart that project for you.</p>]]></content><amg:twitter><![CDATA[While making some updates to the site, I did a 404 scan of my link blog and the results were… less than awesome. So I decided to work some @eleven_ty magic to recover from them.]]></amg:twitter><amg:summary><![CDATA[While making some updates to the site, I did a 404 scan of my link blog and the results were… less than awesome. So I decided to work some Eleventy magic to recover from them.]]></amg:summary><summary type="html"><![CDATA[<p>While making some updates to the site, I did a 404 scan of my link blog and the results were… less than awesome. So I decided to work some Eleventy magic to recover from them.</p>]]></summary><category term="this site" /><category term="URLs" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.aaron-gustafson.com/i/posts/2022-08-31/hero.jpg" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/locking-down-your-github-hosted-domains/</id><title type="html"><![CDATA[✍🏻 Locking down your GitHub-hosted Domains]]></title><link href="https://www.aaron-gustafson.com/notebook/locking-down-your-github-hosted-domains/" rel="alternate" type="text/html" /><published>2022-08-11T20:15:48Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>The other day someone claimed a hostname on a domain I own and it took me a while to track down how. After a lot of digging around, trying to figure out how the hijack was accomplished, it turns out it was via GitHub Pages.</p><p>When you set up a custom domain with GitHub pages, you have to point your domain at GitHub’s servers. <a href="https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/managing-a-custom-domain-for-your-github-pages-site">There are a bunch of ways to do this</a>, but if you use an A record, you need to be careful with your DNS settings. The site in question had a wildcard hostname (*) A record pointed at GitHub’s servers. At the time I’d set it up, that was the recommendation if you wanted all traffic to go to the same place.</p><p>Fast forward a few years and <a href="https://medium.com/@jehy/hijacking-domain-using-github-pages-41c80ac57523">it’s become a known exploit of GitHub Pages</a>: when wildcard hostnames are in play, any repo can add a CNAME file to their repository and claim ownership of a hostname belonging to that domain. GitHub even warns you not to do this anymore, but I hadn’t checked the docs in years. In my particular case, it was an archived domain that I don’t really use anymore, but I wouldn’t have been aware of the DNS hijack if the attacker hadn’t taken the step of claiming the domain on Google’s Webmaster Central.</p><p>Thankfully the fix was simple: Remove the wildcard A record and point the Apex domain at GitHub’s IP addresses.</p><p>If you use GitHub pages to host any of your own domains, I highly recommend auditing their DNS records to ensure this doesn’t happen to you. You can also use <a href="https://docs.github.com/en/pages/configuring-a-custom-domain-for-your-github-pages-site/verifying-your-custom-domain-for-github-pages">domain verification for GitHub Pages</a> and <a href="https://docs.github.com/en/enterprise-cloud@latest/organizations/managing-organization-settings/verifying-or-approving-a-domain-for-your-organization">organizations</a> to further protect yourself.</p>]]></content><amg:twitter><![CDATA[If you use GitHub Pages and don’t have your DNS properly configured, anyone can add a hostname to your domain]]></amg:twitter><amg:summary><![CDATA[The other day someone claimed a hostname on a domain I own and it took me a while to track down how. Turns out it was via GitHub pages.]]></amg:summary><summary type="html"><![CDATA[<p>The other day someone claimed a hostname on a domain I own and it took me a while to track down how. Turns out it was via GitHub pages.</p>]]></summary><category term="hazards" /><category term="URLs" /><category term="the web" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://www.aaron-gustafson.com/i/posts/2022-08-11/hero.jpg" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/links/ios-11-safari-google-amp-sharing-url-scheme/</id><title type="html"><![CDATA[🔗 iOS 11 Safari will turn Google AMP links back into regular ones when sharing]]></title><link href="https://www.aaron-gustafson.com/notebook/links/ios-11-safari-google-amp-sharing-url-scheme/" rel="alternate" type="text/html" /><link href="https://www.theverge.com/2017/8/23/16193584/ios-11-safari-google-amp-sharing-url-scheme" rel="related" type="text/html" /><published>2017-08-25T18:15:43Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<blockquote><p>Nice one Safari team! <a href="https://t.co/YTO6rZR3dd">https://t.co/YTO6rZR3dd</a></p><p>—<a href="https://twitter.com/cramforce/status/900478709215281152">Malte Ubl (@cramforce)</a></p></blockquote><p>This is great to see! I think <code>link[rel=&quot;canonical&quot;]</code> is not used often enough. I’d love to see all sharing protocols adopt this approach for things like cross-posts, m-dot sites, and more.</p>]]></content><category term="browsers" /><category term="URLs" /><category term="HTML" /><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://cdn.vox-cdn.com/thumbor/U0uctblrIw4SFBrfwGsPCAyJXmw=/0x0:842x474/1600x900/cdn.vox-cdn.com/uploads/chorus_image/image/56334257/Screen_Shot_2015-10-07_at_10.20.00_AM.0.0.png" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/avoiding-linkrot-in-print-with-the-help-of-perma-dot-cc/</id><title type="html"><![CDATA[✍🏻 Avoiding Link Rot in Print with the Help of Perma.cc]]></title><link href="https://www.aaron-gustafson.com/notebook/avoiding-linkrot-in-print-with-the-help-of-perma-dot-cc/" rel="alternate" type="text/html" /><published>2015-12-02T21:03:35Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>I think we can all agree, <a href="https://en.wikipedia.org/wiki/Link_rot">link rot</a> is a problem. A 2014 study by Harvard Law School determined that <a href="http://journals.cambridge.org/action/displayAbstract?fromPage=online&amp;aid=9282809&amp;fileId=S1472669614000255/">roughly 50% of the URLs referenced in U.S. Supreme Court opinions no longer work</a>. That’s <em>terrifying</em>.</p><p>When I was mid-way through writing <a href="http://adaptivewebdesign.info/2nd-edition/">the Second Edition of <cite>Adaptive Web Design</cite></a>, I realized that it was pretty likely some of the links I was referencing might disappear over the years. Little did I know, some of them would disappear <em>while I was writing the book!</em></p><p><a href="https://archive.org/web/">The Internet Archive’s Wayback Machine</a> is pretty good, but it doesn’t archive everything, and I often find captured pages end up broken—especially if they rely heavily JavaScript, but often images go missing as well. I wanted to make sure that when you pick up the book a year from now or even 10 years from now, the links will still work.</p><p>I evaluated a few options for creating a permanent archive of each and every link in the book (there are over 200), but then it dawned on me that <a href="https://perma.cc/">Perma.cc</a> might be the perfect answer.</p><p><a href="http://Perma.cc">Perma.cc</a> was created by the <a href="http://librarylab.law.harvard.edu/">Harvard Library Innovation Lab</a> in reaction to the paper I mentioned earlier. It is a distributed archive of URLs for scholarly and legal documents, supported not only by Harvard, but over 90 (<em>and counting!</em>) libraries, distributed all over the world. <a href="https://github.com/harvard-lil/perma">It’s also open source</a>. Each <a href="https://perma.cc/docs#archive-formats">URL is preserved as a live view, an archived view, and a screen capture</a> taken when the link is added. Archived URLs are kept for a minumum of 2 years, but <a href="https://perma.cc/docs#vesting-links">may be “vested” into the permanent archive by a member organization</a>.</p><p>I had contributed some CSS to the project a while back, so I reached out to my contacts to see if they might be interested in vesting all of the links for the book. Turns out they were big fans of <a href="http://adaptivewebdesign.info/1st-edition/">the First Edition</a> and enthusiastically offered their support.</p><p>Converting all of the links took time (and a lot of double- and triple-checking), but the result is that every article, blog post, and web page that I referenced in the book will remain accessible to you in perpetuity. I think that’s pretty awesome. And, as an added bonus, since <a href="http://Perma.cc">Perma.cc</a> creates unique URLs that are relatively short, those of you who read it in print won’t have to re-type the often incredibly-lengthy original URLs.</p><p>I can’t thank <a href="http://mattphillips.info/">Matt Phillips</a>, <a href="https://twitter.com/abziegler">Adam Ziegler</a>, <a href="http://jackcushman.org/">Jack Cushman</a>, and everyone else at the Harvard Library Innovation Lab enough for creating <a href="http://Perma.cc">Perma.cc</a><em>and</em> for offering their service to my readers. You all are amazing!</p>]]></content><amg:summary><![CDATA[When I was mid-way through writing the Second Edition of Adaptive Web Design, I realized that it was pretty likely some of the links I was referencing might disappear over the years.]]></amg:summary><summary type="html"><![CDATA[<p>When I was mid-way through writing the Second Edition of Adaptive Web Design, I realized that it was pretty likely some of the links I was referencing might disappear over the years.</p>]]></summary><category term="the future" /><category term="the web" /><category term="URLs" /><category term="user experience" /><category term="writing" /><category term="hazards" /></entry><entry><id>https://www.aaron-gustafson.com/notebook/url-inception/</id><title type="html"><![CDATA[✍🏻 URL Inception]]></title><link href="https://www.aaron-gustafson.com/notebook/url-inception/" rel="alternate" type="text/html" /><published>2015-05-18T18:38:29Z</published><content type="html" xml:base="https://www.aaron-gustafson.com"><![CDATA[<p>It’s like a snake eating its own tail:</p><p><a href="https://m.facebook.com/ClydesOnMain?refsrc=https%3A%2F%2Fwww.facebook.com%2FClydesOnMain#!/ClydesOnMain?refsrc=https%3A%2F%2Fwww.facebook.com%2FClydesOnMain">https://m.facebook.com/ClydesOnMain?refsrc=https%3A%2F%2Fwww.facebook.com%2FClydesOnMain#!/ClydesOnMain?refsrc=https%3A%2F%2Fwww.facebook.com%2FClydesOnMain</a></p><p>Wonder what’s going on? Well, Facebook’s mobile site (<code><a href="http://m.facebook.com/ClydesOnMain">m.facebook.com/ClydesOnMain</a></code>) is tracking the URL (using the <code>refsrc</code> GET parameter) I came from (<code><a href="http://www.facebook.com/ClydesOnMain#!/ClydesOnMain">www.facebook.com/ClydesOnMain#!/ClydesOnMain</a></code>)—a single page “web app”, hence the hash-bang: <code>#!</code>—that was tracking the original referral page (<code><a href="http://www.facebook.com/ClydesOnMain">www.facebook.com/ClydesOnMain</a></code>).</p><p>I hope they got all that.</p>]]></content><amg:summary><![CDATA[The awesomeness of this URL is almost indescribable.]]></amg:summary><summary type="html"><![CDATA[<p>The awesomeness of this URL is almost indescribable.</p>]]></summary><category term="web design" /><category term="URLs" /></entry></feed>