<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://nicksnell.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://nicksnell.com/" rel="alternate" type="text/html" /><updated>2024-01-01T20:33:02+00:00</updated><id>https://nicksnell.com/feed.xml</id><title type="html">nicksnell.com</title><subtitle>nicksnell.com</subtitle><entry><title type="html">Multi-Region Sites on Netlify</title><link href="https://nicksnell.com/log/2020/06/multi-region-sites-on-netlify/" rel="alternate" type="text/html" title="Multi-Region Sites on Netlify" /><published>2020-06-21T00:00:00+00:00</published><updated>2020-06-21T00:00:00+00:00</updated><id>https://nicksnell.com/log/2020/06/multi-region-sites-on-netlify</id><content type="html" xml:base="https://nicksnell.com/log/2020/06/multi-region-sites-on-netlify/">&lt;p&gt;It’s not immediately obvious on &lt;a href=&quot;https://netlify.com&quot;&gt;Nelify&lt;/a&gt; how you can host multiple sites all under the same domain when using multiple Netlify applications. This is probably because Netlify prefers to map a domain to a particular application, but you can work around this by using rewites to map url paths to sub domains.&lt;/p&gt;

&lt;p&gt;This is really useful should you have a multi-region site where you want to keep all the ‘sites’ under the same domain - rather than split them across different sub-domains or TLD’s.&lt;/p&gt;

&lt;p&gt;So, for example, if you had a site designed for 3 regions: Britain, Ireland &amp;amp; Germany&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;https://raw.githubusercontent.com/nicksnell/mehrere/master/arch.png&quot; alt=&quot;Site Structure&quot; /&gt;&lt;/p&gt;

&lt;p&gt;and you wanted the URL structure to be like the following:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;https://example.com/gb/
https://example.com/ie/
https://example.com/de/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;First you need to great 4 netlify applications, one for each of the site specific apps and an 4th for the master site to redirect to the others. Each of the site specific applications should be mapped to a subdomain. You then end up with a setup like this:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;App &quot;Master&quot; - example.com
App &quot;GB&quot; - gb.example.com
App &quot;IE&quot; - ie.example.com
App &quot;DE&quot; - de.example.com
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;You can then configure the master application to redirect to a site specific app on a specific url path. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;netlify.toml&lt;/code&gt; on the main site looks like this:&lt;/p&gt;

&lt;div class=&quot;language-toml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[[redirects]]&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/gb/*&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://gb.example.com/:splat&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[[redirects]]&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/de/*&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://de.example.com/:splat&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[[redirects]]&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/ie/*&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;https://ie.example.com/:splat&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;_Note: If the site specific applications use absolute URL’s you need to remeber to add the path prefix otherwise the url may be resolved by the master app.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once setup, you can add an additional layer to &lt;a href=&quot;https://docs.netlify.com/routing/redirects/redirect-options/#redirect-by-country-or-language&quot;&gt;redirect the traffic automatically based on the calling users IP address&lt;/a&gt; by adding further redirects to the master sites &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;netlify.toml&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-toml highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nn&quot;&gt;[[redirects]]&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/*&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/gb/&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;302&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;force&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;nn&quot;&gt;conditions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Country&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;[&quot;gb&quot;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[[redirects]]&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/*&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/de/&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;302&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;force&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;nn&quot;&gt;conditions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Country&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;[&quot;de&quot;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nn&quot;&gt;[[redirects]]&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/*&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;/ie/&quot;&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;status&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;302&lt;/span&gt;
  &lt;span class=&quot;py&quot;&gt;force&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;nn&quot;&gt;conditions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;py&quot;&gt;Country&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;[&quot;ie&quot;]&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Once donem these redirects will push users from &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;example.com/&lt;/code&gt; to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;example.com/&amp;lt;site path&amp;gt;&lt;/code&gt; automatically. It can make testing difficult however, so you can override this behaviour by setting a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;nf_country&lt;/code&gt; cookie with the correct &lt;a href=&quot;https://dev.maxmind.com/geoip/legacy/codes/iso3166/&quot;&gt;ISO 3166&lt;/a&gt; country code.&lt;/p&gt;

&lt;p&gt;A full working example can be found on &lt;a href=&quot;https://github.com/nicksnell/mehrere&quot;&gt;Github&lt;/a&gt; and a &lt;a href=&quot;https://thebsides.co.uk/&quot;&gt;sample Netlify app&lt;/a&gt;.&lt;/p&gt;</content><author><name></name></author><summary type="html">It’s not immediately obvious on Nelify how you can host multiple sites all under the same domain when using multiple Netlify applications. This is probably because Netlify prefers to map a domain to a particular application, but you can work around this by using rewites to map url paths to sub domains.</summary></entry><entry><title type="html">Formatting Currency using Javascripts Internationalization API</title><link href="https://nicksnell.com/log/2019/01/formatting-currency-javascript-internationalization-api/" rel="alternate" type="text/html" title="Formatting Currency using Javascripts Internationalization API" /><published>2019-01-27T00:00:00+00:00</published><updated>2019-01-27T00:00:00+00:00</updated><id>https://nicksnell.com/log/2019/01/formatting-currency-javascript-internationalization-api</id><content type="html" xml:base="https://nicksnell.com/log/2019/01/formatting-currency-javascript-internationalization-api/">&lt;p&gt;Javascript has a surprisingly neat (and built-in) way to format currency values using it’s Internationalization API &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Intl&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;It’s the sort of thing thats often forgotten when ‘internatinalising’ sites as the variation of display for numeric values isn’t widely appreciated. But using the Internationalization API it’s really simple to display numbers in the preferred format of your users.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;To format a currency output, use &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NumberFormat&quot;&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Intl.NumberFormat&lt;/code&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currencyFormatter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Intl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;NumberFormat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;de&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;EUR&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;currencyFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;c1&quot;&gt;// -&amp;gt; &quot;100,00 €&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currencyFormatter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Intl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;NumberFormat&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;en&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;currency&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;EUR&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;currencyFormatter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;format&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; 
&lt;span class=&quot;c1&quot;&gt;// -&amp;gt; &quot;€100.00&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It’s a great API but does have some caveats, particularly if you use english formatting on certain currencies. For example, the Swedish currency Krona. With the Swedish &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;sv&lt;/code&gt; locale in place the output will be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;100,00 kr&lt;/code&gt;, so you might expect the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;en&lt;/code&gt; output to be &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;100.00 kr&lt;/code&gt;, however it displays &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;SEK 100.00&lt;/code&gt;, which seems to be a fallback.&lt;/p&gt;

&lt;p&gt;There is an additional argument &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;currencyDisplay&lt;/code&gt; which in theory will enforce the output style, but even with it set to &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;symbol&quot;&lt;/code&gt; (which is actually the default) in this case it doesn’t matter.&lt;/p&gt;</content><author><name></name></author><summary type="html">Javascript has a surprisingly neat (and built-in) way to format currency values using it’s Internationalization API Intl.</summary></entry><entry><title type="html">Getting started with Mutt Forms Vue</title><link href="https://nicksnell.com/log/2018/01/getting-started-with-mutt-forms-vue/" rel="alternate" type="text/html" title="Getting started with Mutt Forms Vue" /><published>2018-01-03T00:00:00+00:00</published><updated>2018-01-03T00:00:00+00:00</updated><id>https://nicksnell.com/log/2018/01/getting-started-with-mutt-forms-vue</id><content type="html" xml:base="https://nicksnell.com/log/2018/01/getting-started-with-mutt-forms-vue/">&lt;p&gt;Mutt Forms Vue (MFV) is an extension to Mutt Forms, a tool for building HTML forms from JSON Schema definitions, to make it compatible with VueJS. By default, Mutt Forms renders HTML forms directly to the DOM, MFV uses Vue templating system in addition to offering some other benefits - like reactive properties.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;MFV was developed in-house at &lt;a href=&quot;https://boughtbymany.com&quot;&gt;Bought By Many&lt;/a&gt;, primarily to get a more robust integration with our VueJS apps. Mutt Forms works directly with the DOM which doesn’t play nicely with Vue, it’s a bit of an anti-pattern to mix these approaches so MFV was born to solve that issue. Like Mutt Forms, it has no dependencies (apart from Vue &amp;amp; Mutt itself) so it’s a tiny addition to any app, and is super fast at rendering even large complicated forms. It’s available for all on a standard MIT license.&lt;/p&gt;

&lt;h3 id=&quot;installing&quot;&gt;Installing&lt;/h3&gt;

&lt;p&gt;MFV is easily installed from NPM, it’s recommended to use &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarn&lt;/code&gt; but &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm&lt;/code&gt; works just fine too:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarn add mutt-forms-vue&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once installed, it can be hooked into Vue like most Vue plugins by using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Vue.use()&lt;/code&gt;. This can be done anywhere during the app initialisation:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;vue&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;MuttVue&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;mutt-forms-vue&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;Vue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;use&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;MuttVue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;use-with-webpack&quot;&gt;Use with Webpack&lt;/h3&gt;

&lt;p&gt;MFV, like Mutt Forms, is written in ES6. You can use it directly but you may need to
adjust your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;babel&lt;/code&gt; setup to have it transpile correctly. To avoid this, a bundled
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dist&lt;/code&gt; version is provided where the module has already been transpiled. You can include
this version using the webpack alias syntax:&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;resolve&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;alias&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;mutt-forms$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;node_modules/mutt-forms/dist/mutt-forms.es.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;mutt-forms-vue$&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;node_modules/mutt-forms-vue/dist/mutt-forms-vue.es.js&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;NOTE: Depending on your setup, you may need a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vue&lt;/code&gt; alias here also, MFV internally uses Vue templates - so you will need the template compiler, &lt;a href=&quot;https://vuejs.org/v2/guide/installation.html#Runtime-Compiler-vs-Runtime-only&quot;&gt;not just the runtime&lt;/a&gt;.&lt;/p&gt;

&lt;h3 id=&quot;getting-started&quot;&gt;Getting started&lt;/h3&gt;

&lt;p&gt;MFV will extend Vue to add the components ‘mutt-vue’, ‘mutt-widget’ &amp;amp; ‘mutt-watcher’, as well as extending Vue to add a hook directly to Mutt (this is available as &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;this.$mutt&lt;/code&gt; inside components). The components can be used to build forms (and form fragments) directly in Vue templates. In the simplest case, you can just pass a JSON schema to a ‘mutt-vue’ component and you will get a form:&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;div&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;mutt-vue&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;v-bind:schema=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;schema&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;v-on:submit=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;”submitForm”&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;

&lt;span class=&quot;nt&quot;&gt;&amp;lt;script&amp;gt;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;demo&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;schema&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;email&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;methods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;submitForm&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;validate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;Submission!&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                &lt;span class=&quot;nx&quot;&gt;JSON&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;stringify&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;form&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;‘mutt-forms-vue’ also takes options, just as Mutt Form objects themselves do - in fact &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutt-forms-vue&lt;/code&gt; components will take all of the arguments you might expect to send to a Mutt Form object.&lt;/p&gt;

&lt;h3 id=&quot;a-bit-deeper&quot;&gt;A bit deeper&lt;/h3&gt;

&lt;p&gt;Under the hood of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutt-vue&lt;/code&gt; component is simply iterating over (along with some helpful layout &amp;amp; functions) a set of Mutt form fields and renders each one using &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutt-widget&lt;/code&gt;. You don’t have to do this however, if you want to create custom layouts or create form fragments you can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutt-widget&lt;/code&gt; component directly.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutt-widget&lt;/code&gt; components expect a field as an argument and will render the corresponding HTML input interface for that field type. The &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutt-widget&lt;/code&gt; component is itself polymorphic, and will inspect the field type to determine exactly how it should render. As is usual with Mutt, you can use field options to override default widgets for a given field, MFV will respect this too.&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;mutt-widget&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;v-bind:field=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;field&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/mutt-widget&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;getting-reactive&quot;&gt;Getting reactive&lt;/h3&gt;

&lt;p&gt;The final MFV component is called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutt-watcher&lt;/code&gt;. These can be used to reflect the value of a given field reactively. Internally MFV will make the field value reactive, which means should it change it will update other components reactively. ‘mutt-watcher’ exploits this, so you can create things like form summary panels or more intricate UI’s. As will &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mutt-widget&lt;/code&gt;, it requires a form field to be bound to it. It will render the field value in a text format in the format &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;field name: &amp;lt;field value&amp;gt;&lt;/code&gt;, there are a few options to aid this display, but by default it will handle all of the data types Mutt understands.&lt;/p&gt;

&lt;p&gt;It has a couple of neat uses, for example displaying the value of a hidden field that’s being updated behind the scenes elsewhere and it can even display form fields that aren’t otherwise rendered in the main form.&lt;/p&gt;

&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nt&quot;&gt;&amp;lt;mutt-watcher&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;v-bind:field=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;field&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/mutt-watcher&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hopefully that covers some of the main features of MFV, there is a &lt;a href=&quot;https://github.com/nicksnell/mfv-getting-started&quot;&gt;git repository&lt;/a&gt; available with all of these code samples in a working demo app. MFV is still under active development but at this stage it’s API can be considered pretty stable.&lt;/p&gt;

&lt;p&gt;(If you end up using MFV in a project, would love to hear your experience!)&lt;/p&gt;</content><author><name></name></author><summary type="html">Mutt Forms Vue (MFV) is an extension to Mutt Forms, a tool for building HTML forms from JSON Schema definitions, to make it compatible with VueJS. By default, Mutt Forms renders HTML forms directly to the DOM, MFV uses Vue templating system in addition to offering some other benefits - like reactive properties.</summary></entry><entry><title type="html">How far ahead of Apple Maps is Google Maps?</title><link href="https://nicksnell.com/log/2017/12/google-map-moat/" rel="alternate" type="text/html" title="How far ahead of Apple Maps is Google Maps?" /><published>2017-12-17T00:00:00+00:00</published><updated>2017-12-17T00:00:00+00:00</updated><id>https://nicksnell.com/log/2017/12/google-map-moat</id><content type="html" xml:base="https://nicksnell.com/log/2017/12/google-map-moat/">&lt;p&gt;As someone who just can’t make the switch to Apple Maps permanently, it’s really no surprise to hear Google is winning this particular battle, but it’s incredible to see just how far ahead it is.&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“Now, you can see 25 million new building footprints that have been added to Google Maps on desktop and mobile across major metropolitan regions in the United States, including Houston, Los Angeles, Chicago, Miami, and the San Francisco Bay Area.”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Great round up of the differences by &lt;a href=&quot;https://www.justinobeirne.com/google-maps-moat&quot;&gt;Justin O’Beirne&lt;/a&gt;.&lt;/p&gt;</content><author><name></name></author><summary type="html">As someone who just can’t make the switch to Apple Maps permanently, it’s really no surprise to hear Google is winning this particular battle, but it’s incredible to see just how far ahead it is.</summary></entry><entry><title type="html">Generating UML Sequence diagrams in Javascript</title><link href="https://nicksnell.com/log/2017/11/uml-sequence-diagrams/" rel="alternate" type="text/html" title="Generating UML Sequence diagrams in Javascript" /><published>2017-11-20T00:00:00+00:00</published><updated>2017-11-20T00:00:00+00:00</updated><id>https://nicksnell.com/log/2017/11/uml-sequence-diagrams</id><content type="html" xml:base="https://nicksnell.com/log/2017/11/uml-sequence-diagrams/">&lt;p&gt;&lt;img src=&quot;/assets/images/2017/sequence-diagram.svg&quot; alt=&quot;UML Sequence Diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;UML might be 20+ years old at this stage but it’s still incredibly useful -
especially when describing a Micro-service world.&lt;/p&gt;

&lt;p&gt;Drawing the diagrams themselves, with a tool like VISO or OmniGraffle, does
get old quite quickly though when changes are rapid.&lt;/p&gt;

&lt;p&gt;I’ve started using &lt;a href=&quot;https://mermaidjs.github.io/&quot;&gt;Mermaid&lt;/a&gt; for generating the
system diagrams from ‘code’ directly. It’s much less work as things change and
is really easy to setup.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;The simplest way to get started is to install the &lt;a href=&quot;https://github.com/mermaidjs/mermaid.cli&quot;&gt;CLI&lt;/a&gt;
version of mermaid:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarn global add mermaid.cli&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Once your up and running, you can produce diagrams by writing out a document
containing the sequence:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;sequenceDiagram
	participant C as Client
	participant MS1 as Microservice 1
	participant MS2 as Microservice 2

    C-&amp;gt;&amp;gt;MS1: Make Request
	activate MS1
    MS1-&amp;gt;&amp;gt;MS2: Internal Request
	activate MS2
	MS2--&amp;gt;&amp;gt;MS1: Data
	deactivate MS2
	MS1--&amp;gt;&amp;gt;C: Response data
	deactivate MS1
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And running the build command:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;mmdc -i test.mmd -o test.svg&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;The syntax for generating the diagrams is reasonably intuitive, but there
are a couple of gotchas - most of which cause the diagram to not render.
It’s worth checking the &lt;a href=&quot;https://mermaid-js.github.io/mermaid/#/sequenceDiagram&quot;&gt;diagram reference&lt;/a&gt; to
make sure your syntax is correct as the CLI interface doesn’t give feedback.&lt;/p&gt;</content><author><name></name></author><summary type="html"></summary></entry><entry><title type="html">Hastilude</title><link href="https://nicksnell.com/log/2017/10/hastilude/" rel="alternate" type="text/html" title="Hastilude" /><published>2017-10-27T00:00:00+00:00</published><updated>2017-10-27T00:00:00+00:00</updated><id>https://nicksnell.com/log/2017/10/hastilude</id><content type="html" xml:base="https://nicksnell.com/log/2017/10/hastilude/">&lt;p&gt;Working with JSON Web Tokens (JWT) can be a bit awkward, particularly
when using the command line to make requests, so I’ve created a little
tool to make life easier.&lt;/p&gt;

&lt;p&gt;It’s called &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hastilude&lt;/code&gt; and is available on NPM, to install run:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;npm install -g hastilude&lt;/code&gt; or &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;yarn global add hastilude&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;It allows for tokens to be generated from a static JSON file as well as
to dissemble encrypted ones into a readable form.&lt;/p&gt;

&lt;!--more--&gt;

&lt;h3 id=&quot;generating-tokens&quot;&gt;Generating tokens&lt;/h3&gt;

&lt;p&gt;You probably already have a payload you want to send in a file (if not, you
need to create one as a JSON string isn’t accepted as an argument), you can
then use hastilude to generate a JWT token from it.&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;test.json&lt;/code&gt;&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;apples&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;oranges&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;black&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;white&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;from the command line, point at the file containing the the payload and
set the secret:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hastilude generate --secret secret --payload test.json&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;This will output the token contents to command line. If you wanted to use
it as a HTTP authorization header, say with &lt;a href=&quot;https://httpie.org/&quot;&gt;HTTPie&lt;/a&gt;, you
can add the  &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;--http&lt;/code&gt; flag to get the output:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Authorization:Bearer &amp;lt;generated token&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;With HTTPie, that looks like:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;http example.org &quot;`hastilude generate -s secret -p test.json --http`&quot;&lt;/code&gt;&lt;/p&gt;

&lt;h3 id=&quot;dismantling-tokens&quot;&gt;Dismantling tokens&lt;/h3&gt;

&lt;p&gt;You can also use hastilude to dismantle a JWT for you:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;hastilude dismantle -t &amp;lt;your jwt token&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;apples&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;oranges&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;black&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;white&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;iat&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1518723649&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;nl&quot;&gt;&quot;exp&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1518725449&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;All contributions welcome, the Project is on &lt;a href=&quot;https://github.com/nicksnell/hastilude&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;</content><author><name></name></author><summary type="html">Working with JSON Web Tokens (JWT) can be a bit awkward, particularly when using the command line to make requests, so I’ve created a little tool to make life easier.</summary></entry><entry><title type="html">Getting the latest commit Hash on Heroku</title><link href="https://nicksnell.com/log/2017/09/heroku-commit-hash/" rel="alternate" type="text/html" title="Getting the latest commit Hash on Heroku" /><published>2017-09-27T00:00:00+00:00</published><updated>2017-09-27T00:00:00+00:00</updated><id>https://nicksnell.com/log/2017/09/heroku-commit-hash</id><content type="html" xml:base="https://nicksnell.com/log/2017/09/heroku-commit-hash/">&lt;p&gt;When you push to &lt;a href=&quot;https://www.heroku.com/&quot;&gt;Heroku&lt;/a&gt;, the contents of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;.git&lt;/code&gt;
directory are usually removed which makes getting the last commit hash a bit
tricky.&lt;/p&gt;

&lt;p&gt;Luckily there is a Heroku labs extension you can use to get some of the git
information back. Just run this command against your app:&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;heroku labs:enable runtime-dyno-metadata -a &amp;lt;app name&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;This will add the following to the env (note - this only happens on the next
deploy after configuring):&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;HEROKU_APP_ID:             4d00253d-b1dc-44dd-9949-106af8002de5
HEROKU_APP_NAME:           &amp;lt;app name&amp;gt;
HEROKU_RELEASE_CREATED_AT: 2018-02-26T21:27:43Z
HEROKU_RELEASE_VERSION:    v13
HEROKU_SLUG_COMMIT:        731b2957b0ec6937cb8bbb0755aa8194e9f02600
HEROKU_SLUG_DESCRIPTION:   Deploy 731b2957
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If you want to use this info in &lt;a href=&quot;https://jekyllrb.com/&quot;&gt;Jeykll&lt;/a&gt;, you can add
a small script to your &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;_plugins&lt;/code&gt; folder to make this available:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;Jekyll&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;EnvVars&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Generator&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;generate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;source_version&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;HEROKU_SLUG_COMMIT&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&amp;lt;dev&amp;gt;&apos;&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;site&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;config&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;release_version&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ENV&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;&apos;HEROKU_RELEASE_VERSION&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&apos;&amp;lt;dev&amp;gt;&apos;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and you can then access the info under the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;{{ site.* }}&lt;/code&gt;.&lt;/p&gt;</content><author><name></name></author><summary type="html">When you push to Heroku, the contents of the .git directory are usually removed which makes getting the last commit hash a bit tricky.</summary></entry><entry><title type="html">Exclude Social login referrals from Google analytics</title><link href="https://nicksnell.com/log/2017/06/exclude-social-login-referrals/" rel="alternate" type="text/html" title="Exclude Social login referrals from Google analytics" /><published>2017-06-03T00:00:00+00:00</published><updated>2017-06-03T00:00:00+00:00</updated><id>https://nicksnell.com/log/2017/06/exclude-social-login-referrals</id><content type="html" xml:base="https://nicksnell.com/log/2017/06/exclude-social-login-referrals/">&lt;p&gt;Social logins can cause havoc with Google Analytics (GA) as visitors are
typically directed away from your domain to the domain of the Social
login provider. This ‘breaks’ the visitors session on your site, making
the resulting return from the social provider appear as if it’s a new
session.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;There are a couple of approaches but it depends on the social login provider.
Google logins are simple enough as they use the domain &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;accounts.google.com&lt;/code&gt;.
This can simply be &lt;a href=&quot;https://support.google.com/analytics/answer/2795830?hl=en&quot;&gt;excluded out right&lt;/a&gt; like you might
with a payment processor (PayPal/Stripe etc..) by adding the domain to the
excluded list.&lt;/p&gt;

&lt;p&gt;Whilst this works for Google, this isn’t as useful for Facebook &amp;amp; Twitter -
particularly if you use either as a way to drive traffic (or even care about
referrals from them). Excluding the domains facebook.com or twitter.com will
block out all referrals - it’s unlikely anyone wants this.&lt;/p&gt;

&lt;p&gt;There doesn’t appear to be a way in GA to handle this scenario via configuration,
there is only a code workaround. The answer is to have GA ‘blank’ the referrals
from these social logins URL’s. You can add the following next to your GA setup:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;refs&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://www.facebook.com/v2.9/dialog/oauth&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://m.facebook.com/v2.9/dialog/oauth/read&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://m.facebook.com/login/checkpoint&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://api.twitter.com/oauth/authorize&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;https://api.twitter.com/oauth/authenticate&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;referrer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;refs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;++&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;referrer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;slice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;refs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;==&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;refs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;ga&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;set&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;referrer&lt;/span&gt;&lt;span class=&quot;dl&quot;&gt;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;dl&quot;&gt;&apos;&apos;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;It should come after the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ga(&apos;create&apos;, ...)&lt;/code&gt; call and before the
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;ga(&apos;send&apos;, &apos;pageview&apos;, ...)&lt;/code&gt; call.&lt;/p&gt;

&lt;p&gt;This will blank the referral from the social logins and stop new sessions
being created.&lt;/p&gt;

&lt;p&gt;NOTE: The example only works for a specific version of the Facebook API, if you
are using another version (not v2.9) you should change the URLs to suit - or
the code could be modified to support multiple versions.&lt;/p&gt;</content><author><name></name></author><summary type="html">Social logins can cause havoc with Google Analytics (GA) as visitors are typically directed away from your domain to the domain of the Social login provider. This ‘breaks’ the visitors session on your site, making the resulting return from the social provider appear as if it’s a new session.</summary></entry><entry><title type="html">Auto-starting MongoDB on Webfaction</title><link href="https://nicksnell.com/log/2014/09/auto-starting-mongodb-webfaction/" rel="alternate" type="text/html" title="Auto-starting MongoDB on Webfaction" /><published>2014-09-02T00:00:00+00:00</published><updated>2014-09-02T00:00:00+00:00</updated><id>https://nicksnell.com/log/2014/09/auto-starting-mongodb-webfaction</id><content type="html" xml:base="https://nicksnell.com/log/2014/09/auto-starting-mongodb-webfaction/">&lt;p&gt;Webfaction is a great host for small websites, particularly if they use a fairly
generic setup, but it can be a bit tricky if you have to start tinkering under the
hood. Unfortunately getting MongoDB running at this time isn’t quite as simple as
using one of the other database options. Webfaction has a
&lt;a href=&quot;https://docs.webfaction.com/software/mongodb.html&quot;&gt;useful guide for setting up MongoDB&lt;/a&gt;
initially but it doesn’t really go into detail about managing the MongoDB
process once it’s all setup.&lt;/p&gt;

&lt;p&gt;One of the omissions from the guide is getting the process to auto-start if the server
reboots, as being a shared server a lot of the standard Linux configurations for
services are out-of-bounds. It can still be accomplished using a Crontab however
and hooking it to a startup script.&lt;/p&gt;

&lt;!--more--&gt;

&lt;p&gt;Once MongoDB is all setup on Webfaction, add three scripts in the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;bin&lt;/code&gt;
directory of the MongoDB app:&lt;/p&gt;

&lt;h4 id=&quot;binstart&quot;&gt;bin/start&lt;/h4&gt;

&lt;script src=&quot;https://gist.github.com/62dcb80d6dcb716c7800.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;&lt;em&gt;NB you need to switch out ‘some port’ with port of the mongo app&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;binstop&quot;&gt;bin/stop&lt;/h4&gt;

&lt;script src=&quot;https://gist.github.com/2b197e97a7666543c70d.js&quot;&gt; &lt;/script&gt;

&lt;h4 id=&quot;binrestart&quot;&gt;bin/restart&lt;/h4&gt;

&lt;script src=&quot;https://gist.github.com/32c8dc92090c3e153521.js&quot;&gt; &lt;/script&gt;

&lt;p&gt;Then edit your crontab to boot Mongo or a system reboot:&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;@reboot $HOME/webapps/mongo_db/bin/start
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Voilà! Auto-rebooting on system reboot. It’s worth noting you may need to add an
additional cron to reboot the process should it fail/crash.&lt;/p&gt;</content><author><name></name></author><summary type="html">Webfaction is a great host for small websites, particularly if they use a fairly generic setup, but it can be a bit tricky if you have to start tinkering under the hood. Unfortunately getting MongoDB running at this time isn’t quite as simple as using one of the other database options. Webfaction has a useful guide for setting up MongoDB initially but it doesn’t really go into detail about managing the MongoDB process once it’s all setup.</summary></entry></feed>