<?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: Sebastian Landwehr</title>
    <description>The latest articles on DEV Community by Sebastian Landwehr (@seblandwehr).</description>
    <link>https://dev.to/seblandwehr</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%2F590637%2F8433eabd-bec5-42cc-a71f-331d48151512.JPG</url>
      <title>DEV Community: Sebastian Landwehr</title>
      <link>https://dev.to/seblandwehr</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/seblandwehr"/>
    <language>en</language>
    <item>
      <title>Creating an RSS Feed from Nuxt Content with Full Body HTML</title>
      <dc:creator>Sebastian Landwehr</dc:creator>
      <pubDate>Sat, 17 Jul 2021 23:49:47 +0000</pubDate>
      <link>https://dev.to/seblandwehr/creating-an-rss-feed-from-nuxt-content-with-full-body-html-code-40i0</link>
      <guid>https://dev.to/seblandwehr/creating-an-rss-feed-from-nuxt-content-with-full-body-html-code-40i0</guid>
      <description>&lt;p&gt;There is already &lt;a href="https://content.nuxtjs.org/integrations/#nuxtjsfeed"&gt;an official doc article&lt;/a&gt; about how to create an RSS feed from Nuxt Content. But it only adds the excerpt as the actual content. Most feed readers allow the reader to read the &lt;strong&gt;whole article&lt;/strong&gt; right in the app without a context switch. This article will present a way to add the whole document to the RSS feed by adding a simple &lt;strong&gt;drop-in module&lt;/strong&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The problem with HTML code outside the nuxt-content component
&lt;/h2&gt;

&lt;p&gt;Nuxt Content is a great static CMS that makes it incredibly easy to setup a performant Markdown-based blog without the need to add loads of third party services.&lt;/p&gt;

&lt;p&gt;The heart of the system is the &lt;code&gt;nuxt-content&lt;/code&gt; component. This component gets the Markdown document that should be rendered, and then applies big magic to make a beautiful blog page out of it 😊.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;nuxt-content&lt;/span&gt; &lt;span class="na"&gt;:document=&lt;/span&gt;&lt;span class="s"&gt;"post"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So far so good. As long as you use Nuxt Content for rendering, there's not much to think about. But as soon as you want to access and work with the &lt;strong&gt;actual generated HTML code&lt;/strong&gt; , you won't find any field in the documents containing the raw HTML code.&lt;/p&gt;

&lt;p&gt;Reason is that the component internally generates a &lt;strong&gt;JSON object&lt;/strong&gt; , which is then turned into VDOM nodes. So it's made for being rendered by Vue.js. There is no native way of letting the Markdown pipeline run somewhere else and working with the HTML code. But this is what we need, since we want to put the article text with markup inside our RSS feed!&lt;/p&gt;

&lt;h2&gt;
  
  
  Use nuxt-content-body-html to abstract it out
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://github.com/dword-design/nuxt-content-body-html"&gt;nuxt-content-body-html&lt;/a&gt;, which basically adds a &lt;code&gt;bodyHtml&lt;/code&gt; field to all markdown documents. It reproduces the Nuxt Content Markdown pipeline to generate it and also uses the Remark and Rehype plugins from the module config, so it outputs the same HTML as the component. The good thing is, we can just drop it in and abstracts away the logic of generating the HTML code, so that we can concentrate on the feed creation.&lt;/p&gt;

&lt;p&gt;Let's install the module by running &lt;code&gt;npm install nuxt-content-body-html&lt;/code&gt;. Then we add it to our &lt;code&gt;nuxt.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-content-body-html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxt/content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great! To test, you can check &lt;code&gt;post.bodyHtml&lt;/code&gt; on a blog page and it should contain the HTML code.&lt;/p&gt;

&lt;p&gt;Now we can adjust the feed creation to actually use the field. You have probably used a way similar to &lt;a href="https://content.nuxtjs.org/integrations/#nuxtjsfeed"&gt;the Nuxt Content docs&lt;/a&gt; to setup your feed. Here is a reduced example of a single RSS feed configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-content-body-html&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxt/content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxtjs/feed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="na"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;create&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nx"&gt;feed&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;$content&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxt/content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;$content&lt;/span&gt;
        &lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;options&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;My Blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;https://me.com/blog&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;It's all about programming!&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;

        &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;$content&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;posts&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sortBy&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;createdAt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;desc&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
        &lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://me.com/blog/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
          &lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
            &lt;span class="na"&gt;author&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;authors&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bodyHtml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;date&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nb"&gt;Date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;createdAt&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
            &lt;span class="na"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;link&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
            &lt;span class="na"&gt;title&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;title&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="p"&gt;})&lt;/span&gt;
        &lt;span class="p"&gt;})&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;path&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/feed&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;rss2&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's it, now you should have a feed with full HTML content! I recommend &lt;a href="https://inoreader.com/"&gt;Inoreader&lt;/a&gt; to test it, you can reload the articles with the little reload button and you should then see changes. Below you can see an example of an article shown in Inoreader:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--AOFQAaNp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sebastianlandwehr.com/blog/creating-an-rss-feed-from-nuxt-content-with-full-body-html-code/post.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--AOFQAaNp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sebastianlandwehr.com/blog/creating-an-rss-feed-from-nuxt-content-with-full-body-html-code/post.jpg" alt="Article in Inoreader"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Bonus tip: Add a teaser image at the very top
&lt;/h2&gt;

&lt;p&gt;Feed readers can not only display the contents of an article, they often also show the first image as a teaser image in the article list. That's a great thing for readers to get a first impression of the article's content! Simply add an image at the very top and you're good to go. Adjust the feed creation like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// images at static/blog/&amp;lt;slug&amp;gt;/banner.png&lt;/span&gt;

&lt;span class="nx"&gt;posts&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;`https://me.com/blog/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;
  &lt;span class="nx"&gt;feed&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addItem&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="c1"&gt;// ...&lt;/span&gt;
    &lt;span class="na"&gt;content&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`
      &amp;lt;p&amp;gt;
        &amp;lt;img
          alt="Cover image"
          src="https://me.com/blog/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;slug&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/teaser.png"
        &amp;gt;
      &amp;lt;/p&amp;gt;
      &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;post&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;bodyHtml&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;
    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Here is the result in Inoreader:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--XqNKSXtX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sebastianlandwehr.com/blog/creating-an-rss-feed-from-nuxt-content-with-full-body-html-code/post-with-image.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--XqNKSXtX--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sebastianlandwehr.com/blog/creating-an-rss-feed-from-nuxt-content-with-full-body-html-code/post-with-image.jpg" alt="Article in Inoreader"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And the resulting teaser view:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://res.cloudinary.com/practicaldev/image/fetch/s--VfDE8Udz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sebastianlandwehr.com/blog/creating-an-rss-feed-from-nuxt-content-with-full-body-html-code/teaser-view.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--VfDE8Udz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://sebastianlandwehr.com/blog/creating-an-rss-feed-from-nuxt-content-with-full-body-html-code/teaser-view.jpg" alt="Teaser view in Inoreader"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;This article was about RSS feeds with Nuxt Content containing full HTML. &lt;a href="https://github.com/dword-design/nuxt-content-body-html"&gt;nuxt-content-body-html&lt;/a&gt; is a quick and easy solution to add a &lt;code&gt;bodyHtml&lt;/code&gt; field to documents that can be used in the feed creation function. I hope it's of some use for you! If you like it, feel free to leave a star at &lt;a href="https://github.com/dword-design/nuxt-content-body-html"&gt;star at GitHub&lt;/a&gt; 🌟. Thanks for reading!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like what I'm doing, follow me on &lt;a href="https://twitter.com/seblandwehr"&gt;Twitter&lt;/a&gt; or check out my &lt;a href="https://sebastianlandwehr.com/"&gt;website&lt;/a&gt;. Also consider donating at &lt;a href="https://www.buymeacoffee.com/dword"&gt;Buy Me a Coffee&lt;/a&gt;, &lt;a href="https://www.paypal.com/paypalme/SebastianLandwehr"&gt;PayPal&lt;/a&gt; or &lt;a href="https://www.patreon.com/dworddesign"&gt;Patreon&lt;/a&gt;. Thank you so much! ❤️&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>vue</category>
      <category>rss</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Generating Beautiful Flowchart Diagrams With Mermaid and Vue/Nuxt</title>
      <dc:creator>Sebastian Landwehr</dc:creator>
      <pubDate>Tue, 29 Jun 2021 16:35:15 +0000</pubDate>
      <link>https://dev.to/seblandwehr/generating-beautiful-flowchart-diagrams-with-mermaid-and-vue-nuxt-4ha6</link>
      <guid>https://dev.to/seblandwehr/generating-beautiful-flowchart-diagrams-with-mermaid-and-vue-nuxt-4ha6</guid>
      <description>&lt;p&gt;Hey folks, today I want to show you how to generate flowchart diagrams in a Vue or Nuxt application using &lt;a href="https://github.com/dword-design/vue-mermaid-string" rel="noopener noreferrer"&gt;vue-mermaid-string&lt;/a&gt; and &lt;a href="https://github.com/dword-design/nuxt-mermaid-string" rel="noopener noreferrer"&gt;nuxt-mermaid-string&lt;/a&gt;. They both help to integrate the wonderful &lt;a href="https://mermaid-js.github.io/" rel="noopener noreferrer"&gt;Mermaid&lt;/a&gt; library into your Vue-based projects.&lt;/p&gt;

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

&lt;p&gt;Alright, let's stick to Vue for now and see later how it works for Nuxt. First we need to install the component.&lt;/p&gt;

&lt;p&gt;There are several ways to add the component to your project. The quickest solution is via CDN like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/vue"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/mermaid/dist/mermaid.min.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://unpkg.com/vue-mermaid-string"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that you also need to add &lt;code&gt;mermaid&lt;/code&gt; itself.&lt;/p&gt;

&lt;p&gt;Alternatively, install it via a package manager:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install &lt;/span&gt;vue-mermaid-string
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And register the component. You can do it locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VueMermaidString&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-mermaid-string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;VueMermaidString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Globally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VueMermaidString&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-mermaid-string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;component&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;VueMermaidString&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;VueMermaidString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or as a plugin:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;Vue&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VueMermaidString&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;vue-mermaid-string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;Vue&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;use&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;VueMermaidString&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Let's draw some serious stuff
&lt;/h2&gt;

&lt;p&gt;Alright, now let's start drawing a diagram! Since probably most of the readers are JavaScript fans, we create a little tech tree for demonstration purposes 😊.&lt;/p&gt;

&lt;p&gt;Here is the code needed to display the diagram. We also add &lt;a href="https://github.com/indentjs/endent" rel="noopener noreferrer"&gt;endent&lt;/a&gt; to make life easier with multi-line strings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"app"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;vue-mermaid-string&lt;/span&gt; &lt;span class="na"&gt;:value=&lt;/span&gt;&lt;span class="s"&gt;"diagram"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;VueMermaidString&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;vue-mermaid-string&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;endent&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;endent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;computed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;diagram&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;endent&lt;/span&gt;&lt;span class="s2"&gt;`
      graph TD
        DateTime[Date and time]

        JavaScript --&amp;gt; Frameworks
        JavaScript --&amp;gt; DateTime
        JavaScript --&amp;gt; 3D
        Frameworks --&amp;gt; Vue.js
        Frameworks --&amp;gt; React
        DateTime --&amp;gt; Moment.js
        DateTime --&amp;gt; date-fns
        3D --&amp;gt; Three.js
        3D --&amp;gt; Babylon.js
    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;components&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;VueMermaidString&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This results in the following diagram:&lt;/p&gt;

&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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynsbhtel05e2wqxxx6ad.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%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fynsbhtel05e2wqxxx6ad.png" alt="Diagram with JavaScript frameworks (Vue.js, React), DateTime libraries (Moment.js, date-fns), and 3D libraries (Three.js, Babylon.js)"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Great! You can also edit the diagram string (for example the node labels), and it updates the result accordingly.&lt;/p&gt;

&lt;p&gt;As a next step we change the colors for each library type. I've used &lt;a href="https://www.paletton.com/#uid=73+1p0k2O++00++00++7n++be+Z" rel="noopener noreferrer"&gt;Paletton&lt;/a&gt; to generate a tetradic color scheme and applied the colors to the corresponding nodes. &lt;/p&gt;

&lt;p&gt;I've put the result into a sandbox with source code, the result looks like this:&lt;/p&gt;

&lt;p&gt;
  &lt;iframe src="https://codesandbox.io/embed/demo-vue-mermaid-string-e2sp4"&gt;
&lt;/iframe&gt;

&lt;/p&gt;

&lt;p&gt;Feel free to play around with the sandbox and try out different Mermaid strings!&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage with Nuxt
&lt;/h2&gt;

&lt;p&gt;If you are a Nuxt user, it is probably more convenient to add a module to your project and then have everything available right away. There is &lt;a href="https://github.com/dword-design/nuxt-mermaid-string" rel="noopener noreferrer"&gt;nuxt-mermaid-string&lt;/a&gt;, which basically wraps the vue component.&lt;/p&gt;

&lt;p&gt;Simply install it via &lt;code&gt;npm install nuxt-mermaid-string&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then add it to your &lt;code&gt;nuxt.config.js&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-mermaid-string&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there we go. The rest works like above!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;In this article we had a look at diagram generation in Vue and Nuxt apps. I hope you liked it and it's of some use for you!&lt;/p&gt;

&lt;p&gt;You help me know if people like the packages by leaving a GitHub star at &lt;a href="https://github.com/dword-design/vue-mermaid-string" rel="noopener noreferrer"&gt;vue-mermaid-string&lt;/a&gt; and/or &lt;a href="https://github.com/dword-design/vue-mermaid-string" rel="noopener noreferrer"&gt;nuxt-mermaid-string&lt;/a&gt; 🌟.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like what I'm doing, follow me on &lt;a href="https://twitter.com/seblandwehr" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; or check out my &lt;a href="https://sebastianlandwehr.com" rel="noopener noreferrer"&gt;website&lt;/a&gt;. Also consider donating at &lt;a href="https://www.buymeacoffee.com/dword" rel="noopener noreferrer"&gt;Buy Me a Coffee&lt;/a&gt;, &lt;a href="https://www.paypal.com/paypalme/SebastianLandwehr" rel="noopener noreferrer"&gt;PayPal&lt;/a&gt; or &lt;a href="https://www.patreon.com/dworddesign" rel="noopener noreferrer"&gt;Patreon&lt;/a&gt;. Thank you so much! ❤️&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>vue</category>
      <category>nuxt</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How to Access Nuxt.js Page Data in Route Meta Fields</title>
      <dc:creator>Sebastian Landwehr</dc:creator>
      <pubDate>Thu, 13 May 2021 13:09:25 +0000</pubDate>
      <link>https://dev.to/seblandwehr/how-to-access-nuxt-js-page-data-in-route-objects-klf</link>
      <guid>https://dev.to/seblandwehr/how-to-access-nuxt-js-page-data-in-route-objects-klf</guid>
      <description>&lt;p&gt;Hey folks, this article is about accessing page data in route objects. It's a use case I have frequently stumbled upon, for example when generating sitemaps.&lt;/p&gt;

&lt;p&gt;Nuxt pages allow you to define structural data like the &lt;a href="https://github.com/nuxt/nuxt.js/issues/1687"&gt;meta&lt;/a&gt; property or the &lt;a href="https://auth.nuxtjs.org/guide/middleware"&gt;auth property from @nuxtjs/auth&lt;/a&gt; (note that they should not be confused with &lt;a href="https://nuxtjs.org/docs/2.x/features/meta-tags-seo"&gt;meta tags&lt;/a&gt;). It would be great to be able to access them elsewhere. The route object can be accessed at quite a lot of places:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;context.route&lt;/code&gt; in &lt;code&gt;asyncData&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;this.$route.meta&lt;/code&gt; in components&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;this.extendRoutes&lt;/code&gt; in modules&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;context.route&lt;/code&gt; in Middlewares&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I did some testing and found out that the only possibility to access page data outside pages is in &lt;code&gt;asyncData&lt;/code&gt; and middlewares, as discussed in &lt;a href="https://github.com/nuxt/nuxt.js/issues/1687"&gt;this issue&lt;/a&gt;. All other places do not work and have empty &lt;code&gt;meta&lt;/code&gt; objects. Also, the case discussed in the linked issue adds a &lt;code&gt;meta&lt;/code&gt; property in the route object itself, not in the &lt;code&gt;matched&lt;/code&gt; array, as it is in vue-router (see the &lt;a href="https://router.vuejs.org/guide/advanced/meta.html"&gt;example from vue-router&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Alright, that's the current state. Now, how can we fix it and add page data to route objects?&lt;/p&gt;

&lt;h2&gt;
  
  
  nuxt-route-meta
&lt;/h2&gt;

&lt;p&gt;I wrote the &lt;a href="https://github.com/dword-design/nuxt-route-meta"&gt;nuxt-route-meta&lt;/a&gt; module that does it by parsing the page components at build time and adding the data to the routes via &lt;code&gt;this.extendRoutes&lt;/code&gt;. It's a zero config module, so you can just add it to your &lt;code&gt;nuxt.config.js&lt;/code&gt; and it works out of the box.&lt;/p&gt;

&lt;p&gt;First, install it via &lt;code&gt;npm install nuxt-route-meta&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then add it to your &lt;code&gt;nuxt.config.js&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// nuxt.config.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-route-meta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now let's create a page with some data like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/index.vue&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are already done with the configuration! Let's go through the cases discussed above:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;asyncData&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/index.vue&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;asyncData&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// route.matched[0].meta.auth = true&lt;/span&gt;
    &lt;span class="c1"&gt;// route.matched[0].meta.theme = 'light'&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;this.$route.meta&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// pages/index.vue&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;theme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;light&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="nx"&gt;mouted&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;// this.$route.meta.auth = true&lt;/span&gt;
    &lt;span class="c1"&gt;// this.$route.meta.theme = 'light'&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;this.extendRoutes&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// modules/module.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extendRoutes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
    &lt;span class="nx"&gt;routes&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;forEach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="c1"&gt;// route.meta.auth = true&lt;/span&gt;
      &lt;span class="c1"&gt;// route.meta.theme = 'light'&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Middlewares&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// middleware/middleware.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// route.matched[0].meta.auth = true&lt;/span&gt;
  &lt;span class="c1"&gt;// route.matched[0].meta.theme = 'light'&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As we can see, we can access the page data everywhere now! That's it already on how to use the module.&lt;/p&gt;

&lt;h2&gt;
  
  
  Generating a sitemap with non-auth routes
&lt;/h2&gt;

&lt;p&gt;A common use case of accessing page data is sitemap generation, especially conditionally adding entries to the sitemap. We will now configure &lt;code&gt;@nuxtjs/sitemap&lt;/code&gt; to only add non-auth routes. So let's add the sitemap module via &lt;code&gt;npm install @nuxtjs/sitemap&lt;/code&gt; and add it to our config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// nuxt.config.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-route-meta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxtjs/sitemap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Filtering the routes is easy now because we only have to check the meta property:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// nuxt.config.js&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-route-meta&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
  &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxtjs/sitemap&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;routes&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
      &lt;span class="nx"&gt;routes&lt;/span&gt;
        &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;guest&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nx"&gt;includes&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;route&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;meta&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
  &lt;span class="p"&gt;}],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And that's it, if you check &lt;code&gt;/sitemap.xml&lt;/code&gt;, you should only see non-auth routes!&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That was an introduction to &lt;a href="https://github.com/dword-design/nuxt-route-meta"&gt;nuxt-route-meta&lt;/a&gt;. I hope it's of some use for you! If you like it, feel free to leave a star at &lt;a href="https://github.com/dword-design/nuxt-route-meta"&gt;star at GitHub&lt;/a&gt; 🌟. Also, the module probably needs some more work, so in case you need something or there is a bug, &lt;a href="https://github.com/dword-design/nuxt-route-meta/issues"&gt;file an issue&lt;/a&gt;. Thanks for reading!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like what I'm doing, follow me on &lt;a href="https://twitter.com/seblandwehr"&gt;Twitter&lt;/a&gt; or check out my &lt;a href="https://sebastianlandwehr.com"&gt;website&lt;/a&gt;. Also consider donating at &lt;a href="https://www.buymeacoffee.com/dword"&gt;Buy Me a Coffee&lt;/a&gt;, &lt;a href="https://www.paypal.com/paypalme/SebastianLandwehr"&gt;PayPal&lt;/a&gt; or &lt;a href="https://www.patreon.com/dworddesign"&gt;Patreon&lt;/a&gt;. Thank you so much! ❤️&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>vue</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>How to Write File-Based JavaScript Tests With Real Files</title>
      <dc:creator>Sebastian Landwehr</dc:creator>
      <pubDate>Wed, 21 Apr 2021 10:47:47 +0000</pubDate>
      <link>https://dev.to/seblandwehr/how-to-write-file-based-tests-with-real-files-26ek</link>
      <guid>https://dev.to/seblandwehr/how-to-write-file-based-tests-with-real-files-26ek</guid>
      <description>&lt;p&gt;Hey guys, this post is about writing tests for projects that access the file system by reading and writing files to disk.&lt;/p&gt;

&lt;p&gt;A lot of my past projects in some way had to do with file access. I started to test with mocking libraries like &lt;a href="https://github.com/tschaub/mock-fs"&gt;mock-fs&lt;/a&gt;, but soon recognized that they do not work for all cases, and sometimes you are using third party libraries internally that you cannot mock easily. So I thought of a different solution and the one I'm using right now for most projects actually uses real files.&lt;/p&gt;

&lt;h2&gt;
  
  
  with-local-tmp-dir and output-files
&lt;/h2&gt;

&lt;p&gt;Why not use real files for testing instead of mocking? I built an NPM package called &lt;a href="https://github.com/dword-design/with-local-tmp-dir"&gt;with-local-tmp-dir&lt;/a&gt; that basically creates a temporary subfolder inside cwd, &lt;code&gt;cd&lt;/code&gt;s into it, runs a function, and &lt;code&gt;cd&lt;/code&gt;s back to the previous cwd afterwards. In this function you can create files and pretty much anything, run your unit under test. Afterwards the folder is removed and everything is cleaned up. You actually do not solely need to use it for tests, you can use it anywhere, but it's mostly useful for tests.&lt;/p&gt;

&lt;p&gt;I also wrote another helper package &lt;a href="https://github.com/dword-design/output-files"&gt;output-files&lt;/a&gt; that creates a whole file tree at once by passing an object. It's much easier than writing a lot of &lt;code&gt;fs.writeFile&lt;/code&gt; calls to create many files.&lt;/p&gt;

&lt;h2&gt;
  
  
  Let's test a scaffolding tool!
&lt;/h2&gt;

&lt;p&gt;Alright, let's dive into it! First of all you need a testing framework. I'm going to use &lt;a href="https://github.com/mochajs/mocha"&gt;Mocha&lt;/a&gt; here, but you can also use &lt;a href="https://github.com/facebook/jest"&gt;Jest&lt;/a&gt; or any other framework of your choice. I'm also using &lt;a href="https://github.com/mjackson/expect"&gt;expect&lt;/a&gt; for assertions. After that, we'll install some packages that we need to write our tests:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/dword-design/with-local-tmp-dir"&gt;with-local-tmp-dir&lt;/a&gt; to create our temporary testing folder.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/dword-design/output-files"&gt;output-files&lt;/a&gt; to create multiple files at once.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/jprichardson/node-fs-extra"&gt;fs-extra&lt;/a&gt; to read files after running the scaffolding tool.&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/zhouhanseng/endent"&gt;endent&lt;/a&gt; to declare multi-line strings.
&lt;/li&gt;
&lt;/ul&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;--save-dev&lt;/span&gt; with-local-tmp-dir output-files fs-extra endent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We are going to test a small scaffolding tool that writes config files to disk. If a file already exists, it is not overwritten. Otherwise a default file is created. It's actually not important how it works but how we test it 😀.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing our first test
&lt;/h2&gt;

&lt;p&gt;Let's add a test file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.spec.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withLocalTmpDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;with-local-tmp-dir&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;endent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs-extra&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scaffold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;no existing files&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;withLocalTmpDir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;scaffold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;README.md&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endent&lt;/span&gt;&lt;span class="s2"&gt;`
      ## Package

      This is a test package.
    `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.configrc.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endent&lt;/span&gt;&lt;span class="s2"&gt;`
      {
        "name": "Package"
      }
    `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we can run our test via:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;mocha index.spec.js
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Pretty neat already, we have tested if the scaffolding tool creates a &lt;code&gt;README.md&lt;/code&gt; and a &lt;code&gt;.configrc.json&lt;/code&gt; file and checks if the contents are correct!&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing files beforehand
&lt;/h2&gt;

&lt;p&gt;Let's add another test that checks if the files are preserved if they are already existing. We are going to use &lt;code&gt;output-files&lt;/code&gt; to write those files.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.spec.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withLocalTmpDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;with-local-tmp-dir&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;outputFiles&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;output-files&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;endent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs-extra&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scaffold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;existing files&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;withLocalTmpDir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;outputFiles&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;README.md&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;endent&lt;/span&gt;&lt;span class="s2"&gt;`
      ## My Package

      Here is how to use this package.
    `&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.configrc.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;endent&lt;/span&gt;&lt;span class="s2"&gt;`
      {
        "name": "My Package"
      }
    `&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;scaffold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;README.md&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endent&lt;/span&gt;&lt;span class="s2"&gt;`
      ## My Package

      Here is how to use this package.
    `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.configrc.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endent&lt;/span&gt;&lt;span class="s2"&gt;`
      {
        "name": "My Package"
      }
    `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Great, that's already most of the work! Of course you can go into detail now and write more tests, but technically that's all it needs. You see, writing file-based tests with these packages is not a lot of more work than without them and you can use real files for your tests 🚀.&lt;/p&gt;

&lt;h2&gt;
  
  
  Writing Git-based tests
&lt;/h2&gt;

&lt;p&gt;The test setup actually opens up another door: Using Git repositories for tests! I know this sounds a bit scary at first, but now that we can write files to disk for our tests, why not &lt;code&gt;git init&lt;/code&gt; a git repository?&lt;/p&gt;

&lt;p&gt;Let's assume that our scaffolding tool makes use of the currently checked out Git repository and puts the origin URL into the &lt;code&gt;.configrc.json&lt;/code&gt; file. Now we can test if this works by actually instantiating a Git repository in our testing folder. We need another package for running child processes, run &lt;code&gt;npm install --save-dev execa&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;// index.spec.js&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;withLocalTmpDir&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;with-local-tmp-dir&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;endent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;endent&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs-extra&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;execa&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;execa&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;scaffold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;uses repository url&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;withLocalTmpDir&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;git init&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;git config user.email "foo@bar.de"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;git config user.name "foo"&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;execa&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;command&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;git remote add origin git@github.com:foo/bar.git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;scaffold&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;README.md&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endent&lt;/span&gt;&lt;span class="s2"&gt;`
      ## Package

      This is a test package.
    `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;.configrc.json&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;utf8&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toEqual&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;endent&lt;/span&gt;&lt;span class="s2"&gt;`
      {
        "name": "Package",
        "repo": "git@github.com:foo/bar.git"
      }
    `&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Be cautious though, if the repository is not initialized correctly, user user Git config might be overridden.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You see there are plenty of possibilities! 🥳 What do you think about this? Let me know in the comments! Also, if you like &lt;a href="https://github.com/dword-design/with-local-tmp-dir"&gt;with-local-tmp-dir&lt;/a&gt; and &lt;a href="https://github.com/dword-design/output-files"&gt;output-files&lt;/a&gt;, give it a star on GitHub 🌟.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like what I'm doing, follow me on &lt;a href="https://twitter.com/seblandwehr"&gt;Twitter&lt;/a&gt; or check out my &lt;a href="https://sebastianlandwehr.com"&gt;website&lt;/a&gt;. Also consider donating at &lt;a href="https://www.buymeacoffee.com/dword"&gt;Buy Me a Coffee&lt;/a&gt;, &lt;a href="https://www.paypal.com/paypalme/SebastianLandwehr"&gt;PayPal&lt;/a&gt; or &lt;a href="https://www.patreon.com/dworddesign"&gt;Patreon&lt;/a&gt;. Thank you so much! ❤️&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>node</category>
      <category>testing</category>
      <category>mocha</category>
    </item>
    <item>
      <title>@nuxt/content: How to Keep createdAt and updatedAt Valid After Cloning</title>
      <dc:creator>Sebastian Landwehr</dc:creator>
      <pubDate>Tue, 13 Apr 2021 22:53:46 +0000</pubDate>
      <link>https://dev.to/seblandwehr/valid-createdat-and-updatedat-dates-with-nuxt-content-after-clones-using-the-git-history-i0h</link>
      <guid>https://dev.to/seblandwehr/valid-createdat-and-updatedat-dates-with-nuxt-content-after-clones-using-the-git-history-i0h</guid>
      <description>&lt;p&gt;I recently tried out &lt;a href="https://github.com/nuxt/content"&gt;@nuxt/content&lt;/a&gt;, a Git-based CMS for Nuxt projects. And I really like it! It allows me to write markdown files and host them right in my existing project.&lt;/p&gt;

&lt;p&gt;One thing I noticed when deploying the project to my server was that the &lt;code&gt;createdAt&lt;/code&gt; and &lt;code&gt;updatedAt&lt;/code&gt; fields were always reset and didn't reflect the actual dates. The reason for this is that Git does not keep file metadata. This means that the timestamps that &lt;code&gt;@nuxt/content&lt;/code&gt; relies on are of no use.&lt;/p&gt;

&lt;h2&gt;
  
  
  Git to the rescue!
&lt;/h2&gt;

&lt;p&gt;One way to fix this is not to use the file stats, but instead use the Git history for this. Special thanks to &lt;a href="http://andrewkreuzer.ca"&gt;Andrew Kreuzer&lt;/a&gt; for the initial idea. We check the history for each file and take the earliest commit date as &lt;code&gt;createdAt&lt;/code&gt; and the latest as &lt;code&gt;updatedAt&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Requirement for this is that Git is installed on the build system and that the history is actually checked out. There will be problems if a shallow clone is made on CI, in this case the cloning has to be configured accordingly.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using the nuxt-content-git module to make things easy
&lt;/h2&gt;

&lt;p&gt;I created the Nuxt module &lt;a href="https://github.com/dword-design/nuxt-content-git"&gt;nuxt-content-git&lt;/a&gt; to make the setup plug-and-play. You probably do not want to reinvent the wheel in each project.&lt;/p&gt;

&lt;p&gt;Install the module with &lt;code&gt;npm install nuxt-content-git&lt;/code&gt; and add it to your &lt;code&gt;nuxt.config.js&lt;/code&gt; like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-content-git&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxt/content&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that it is important to add it &lt;strong&gt;before&lt;/strong&gt; &lt;code&gt;@nuxt/content&lt;/code&gt;, so &lt;code&gt;@nuxt/content&lt;/code&gt; knows about the hooks that our helper module installs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That was basically it! The rest works behind the scenes. Your dates should be up to &lt;em&gt;date&lt;/em&gt; 😊.&lt;/p&gt;

&lt;p&gt;Let me know if you like this module and leave a &lt;a href="https://github.com/dword-design/nuxt-content-git"&gt;star at GitHub&lt;/a&gt; 🌟.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like what I'm doing, follow me on &lt;a href="https://twitter.com/seblandwehr"&gt;Twitter&lt;/a&gt; or check out my &lt;a href="https://sebastianlandwehr.com"&gt;website&lt;/a&gt;. Also consider donating at &lt;a href="https://www.buymeacoffee.com/dword"&gt;Buy Me a Coffee&lt;/a&gt;, &lt;a href="https://www.paypal.com/paypalme/SebastianLandwehr"&gt;PayPal&lt;/a&gt; or &lt;a href="https://www.patreon.com/dworddesign"&gt;Patreon&lt;/a&gt;. Thank you so much! ❤️&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>vue</category>
      <category>webdev</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Using Modernizr with Nuxt.js to Detect Browser Features</title>
      <dc:creator>Sebastian Landwehr</dc:creator>
      <pubDate>Wed, 10 Mar 2021 14:00:57 +0000</pubDate>
      <link>https://dev.to/seblandwehr/using-modernizr-with-nuxt-js-to-detect-browser-features-5g78</link>
      <guid>https://dev.to/seblandwehr/using-modernizr-with-nuxt-js-to-detect-browser-features-5g78</guid>
      <description>&lt;h2&gt;
  
  
  What is Modernizr?
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/Modernizr/Modernizr"&gt;Modernizr&lt;/a&gt; is a package that detects browser features and makes them queriable via JavaScript and CSS. This is very handy to find out which CSS properties are supported, for example. The approach is much more flexible and stable than using browser vendor and version for this. I wrote a module that allows to use Modernizr with Nuxt.js.&lt;/p&gt;

&lt;h2&gt;
  
  
  Using Modernizr with Nuxt.js
&lt;/h2&gt;

&lt;p&gt;Modernizr uses a plugin-based architecture, and you have to build the package yourself, depending on the features you need to detect – at least if you are not using Nuxt.js! I have created the &lt;a href="https://github.com/dword-design/nuxt-modernizr"&gt;nuxt-modernizr&lt;/a&gt; module that makes it easy to add Modernizr to your Nuxt.js app. You pass the features as module options, and the module creates a Modernizr build and places it in the &lt;code&gt;.nuxt&lt;/code&gt; folder. Here is how to configure it:&lt;/p&gt;

&lt;p&gt;First, install the module via &lt;code&gt;npm install nuxt-modernizr&lt;/code&gt; or &lt;code&gt;yarn add nuxt-modernizr&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then, in your &lt;code&gt;nuxt.config.js&lt;/code&gt;, add the module and pass the options that should be passed to Modernizr:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-modernizr&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;feature-detects&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css/scrollbars&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;css/overflow-scrolling&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="na"&gt;options&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;setClasses&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check out the &lt;a href="https://modernizr.com/docs/"&gt;Modernizr documentation&lt;/a&gt; for details.&lt;/p&gt;

&lt;p&gt;Now we can use the &lt;code&gt;Modernizr&lt;/code&gt; variable and the generated CSS classes on the HTML root element to check for browser features. My all-time favorite among browser features is CSS scrollbars, because the support is pretty different between browsers and depending on if they are available, you can adjust container sizes and style them or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Modernizr&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cssscrollbar&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// CSS scrollbar support&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="nc"&gt;.cssscrollbar&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c"&gt;/* CSS scrollbar support */&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That was already it! Usage is pretty simple. Let me know if you find it useful or if there are any things that you are missing. Also, if you find it useful, leave a &lt;a href="https://github.com/dword-design/nuxt-modernizr"&gt;GitHub star on the repository&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like what I'm doing, follow me on &lt;a href="https://twitter.com/seblandwehr"&gt;Twitter&lt;/a&gt; or check out my &lt;a href="https://sebastianlandwehr.com"&gt;website&lt;/a&gt;. Also consider donating at &lt;a href="https://www.buymeacoffee.com/dword"&gt;Buy Me a Coffee&lt;/a&gt;, &lt;a href="https://www.paypal.com/paypalme/SebastianLandwehr"&gt;PayPal&lt;/a&gt; or &lt;a href="https://www.patreon.com/dworddesign"&gt;Patreon&lt;/a&gt;. Thank you so much! ❤️&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>vue</category>
      <category>javascript</category>
      <category>node</category>
    </item>
    <item>
      <title>Image Snapshot Testing with Mocha</title>
      <dc:creator>Sebastian Landwehr</dc:creator>
      <pubDate>Fri, 05 Mar 2021 23:31:15 +0000</pubDate>
      <link>https://dev.to/seblandwehr/image-snapshot-testing-with-mocha-15df</link>
      <guid>https://dev.to/seblandwehr/image-snapshot-testing-with-mocha-15df</guid>
      <description>&lt;p&gt;Snapshot testing is a testing mechanism that for long has seemed to be exclusive to &lt;a href="https://github.com/facebook/jest"&gt;Jest&lt;/a&gt;. The main idea is to generate expected values into a separate file and to compare the actual tested values with these saved values. It is also possible to update snapshots by passing an environment variable. This testing approach is great for complex data like large strings, DOM content, or images. I wrote a package to use image snapshot testing also with &lt;a href="https://github.com/mochajs/mocha"&gt;Mocha&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Snapshot testing with Jest
&lt;/h2&gt;

&lt;p&gt;Snapshot testing itself is a &lt;a href="https://jestjs.io/docs/en/snapshot-testing"&gt;built-in feature&lt;/a&gt; of Jest, and when searching specifically for image snapshots, you'll quickly find &lt;a href="https://github.com/americanexpress/jest-image-snapshot"&gt;jest-image-snapshot&lt;/a&gt;, which does great work comparing and updating image snapshots. It also provides convenience features like a base64 diff output, which allows us to view the diff from a CI environment (since the diff image file cannot be saved or viewed).&lt;/p&gt;

&lt;h2&gt;
  
  
  What about Mocha?
&lt;/h2&gt;

&lt;p&gt;While this is all great, what if I'm not using Jest for whatever reason? What if I'm using Mocha? &lt;/p&gt;

&lt;p&gt;For simple snapshot testing, there are some options. For Chai users, there is &lt;a href="https://github.com/monojitb02/mocha-chai-snapshot"&gt;mocha-chai-snapshot&lt;/a&gt;. For expect users, there is &lt;a href="https://github.com/blogfoster/expect-mocha-snapshot"&gt;expect-mocha-snapshot&lt;/a&gt;. It basically wraps the jest snapshot logic by injecting an artificial testing context. Big credit to &lt;a href="https://github.com/alexbeletsky"&gt;Alexander Beletsky&lt;/a&gt; here!&lt;/p&gt;

&lt;p&gt;What was still missing was a package that ports image snapshot testing to Mocha. Since I'm currently using expect as an assertion library, I focused on finding a solution for this one.&lt;/p&gt;

&lt;p&gt;I started to fiddle around with jest-image-snapshot in combination with expect-mocha-snapshot, and it turned out to be way easier than expected to make it Mocha compatible. I put it into its own NPM package, called &lt;a href="https://github.com/dword-design/expect-mocha-image-snapshot"&gt;expect-mocha-image-snapshot&lt;/a&gt;. Usage is pretty similar to Jest, you only have to pass the testing context via &lt;code&gt;this&lt;/code&gt;. Here is a quick code sample:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;expect&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expect&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;toMatchImageSnapshot&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;expect-mocha-image-snapshot&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;

&lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;extend&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;toMatchImageSnapshot&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;it&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;works&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;...&lt;/span&gt;
  &lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;screenshot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;puppeteer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;screenshot&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
  &lt;span class="nx"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;screenshot&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;toMatchImageSnapshot&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can have a look at the code in case you are interested in how it works. It is pretty straight-forward.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;That was my guide to image snapshot testing with Mocha. If you like &lt;a href="https://github.com/dword-design/expect-mocha-image-snapshot"&gt;expect-mocha-image-snapshot&lt;/a&gt;, you can support me by putting a star on GitHub. Also, let me know what you think about it.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like what I'm doing, follow me on &lt;a href="https://twitter.com/seblandwehr"&gt;Twitter&lt;/a&gt; or check out my &lt;a href="https://sebastianlandwehr.com"&gt;website&lt;/a&gt;. Also consider donating at &lt;a href="https://www.buymeacoffee.com/dword"&gt;Buy Me a Coffee&lt;/a&gt;, &lt;a href="https://www.paypal.com/paypalme/SebastianLandwehr"&gt;PayPal&lt;/a&gt; or &lt;a href="https://www.patreon.com/dworddesign"&gt;Patreon&lt;/a&gt;. Thank you so much! ❤️&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>mocha</category>
      <category>testing</category>
      <category>javascript</category>
      <category>frontend</category>
    </item>
    <item>
      <title>Sending Emails with Nuxt.js the Easy Way</title>
      <dc:creator>Sebastian Landwehr</dc:creator>
      <pubDate>Fri, 05 Mar 2021 01:18:24 +0000</pubDate>
      <link>https://dev.to/seblandwehr/sending-emails-with-nuxt-js-the-easy-way-2n51</link>
      <guid>https://dev.to/seblandwehr/sending-emails-with-nuxt-js-the-easy-way-2n51</guid>
      <description>&lt;p&gt;When I started to work with Nuxt.js, I frequently had the problem that I wanted so send emails via a contact form. While there are third party services to do that, I thought: Why not use the existing server infrastructure that comes with Nuxt.js?&lt;/p&gt;

&lt;p&gt;That is why I wrote &lt;a href="https://github.com/dword-design/nuxt-mail"&gt;nuxt-mail&lt;/a&gt;, a Nuxt.js module that adds a &lt;code&gt;/mail/send&lt;/code&gt; route to the server and injects a &lt;code&gt;$mail&lt;/code&gt; variable that wraps the API call.&lt;/p&gt;

&lt;h2&gt;
  
  
  Usage
&lt;/h2&gt;

&lt;p&gt;You start by installing the module and &lt;a href="https://github.com/axios/axios"&gt;@nuxtjs/axios&lt;/a&gt; via &lt;code&gt;npm install nuxt-mail @nuxtjs/axios&lt;/code&gt; or &lt;code&gt;yarn add nuxt-mail @nuxtjs/axios&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;@nuxtjs/axios&lt;/code&gt; is important here because it allows the module to do the REST call.&lt;/p&gt;

&lt;p&gt;Then you add &lt;code&gt;@nuxtjs/axios&lt;/code&gt; and &lt;code&gt;nuxt-mail&lt;/code&gt; to your &lt;code&gt;nuxt.config.js&lt;/code&gt; file. We have to pass the SMPT settings that should internally be used by &lt;code&gt;nodemailer&lt;/code&gt;. We also configure the recipients here for security reasons. This way, a client cannot send emails to arbitrary recipients from your SMTP server. You can actually preconfigure the messages here in case you always want to give them the same title, from address or something.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxtjs/axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-mail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;me@gmail.com&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="na"&gt;smtp&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="na"&gt;host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;smtp.mailtrap.io&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;port&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;2525&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="na"&gt;user&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;username&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="na"&gt;pass&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;password&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;
        &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;},&lt;/span&gt;
    &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Note that you probably should pass the credentials or the whole config via environment variables (e.g. via &lt;a href="https://github.com/motdotla/dotenv"&gt;dotenv&lt;/a&gt;). Also note that you cannot use this module for static sites (via &lt;code&gt;nuxt generate&lt;/code&gt;), because the server middleware does not exist.&lt;/p&gt;

&lt;p&gt;And there we go! Now we can implement ourselves a contact form page and send emails:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;template&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;form&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Your email address:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;input&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"email"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;label&lt;/span&gt; &lt;span class="na"&gt;for=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Message:&lt;span class="nt"&gt;&amp;lt;/label&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;textarea&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="na"&gt;v-model=&lt;/span&gt;&lt;span class="s"&gt;"message"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;button&lt;/span&gt; &lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"submit"&lt;/span&gt; &lt;span class="err"&gt;@&lt;/span&gt;&lt;span class="na"&gt;click.prevent=&lt;/span&gt;&lt;span class="s"&gt;"send"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Send email
    &lt;span class="nt"&gt;&amp;lt;/button&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/form&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/template&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the &lt;code&gt;&amp;lt;script&amp;gt;&lt;/code&gt; section we basically call &lt;code&gt;this.$mail.send()&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nx"&gt;script&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;data&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}),&lt;/span&gt;
  &lt;span class="na"&gt;methods&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$mail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;send&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
        &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Contact form message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;message&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="p"&gt;})&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="sr"&gt;/script&lt;/span&gt;&lt;span class="err"&gt;&amp;gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When you hit the &lt;code&gt;Send&lt;/code&gt; button now, you should receive an email into your inbox!&lt;/p&gt;

&lt;h2&gt;
  
  
  Multiple message configs
&lt;/h2&gt;

&lt;p&gt;It is also possible to provide multiple message configurations by changing the &lt;code&gt;message&lt;/code&gt; config into an array.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;modules&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
    &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@nuxtjs/axios&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;nuxt-mail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contact&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;contact@foo.de&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;support&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="na"&gt;to&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;support@foo.de&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
      &lt;span class="p"&gt;],&lt;/span&gt;
      &lt;span class="p"&gt;...&lt;/span&gt;
    &lt;span class="p"&gt;}],&lt;/span&gt;
  &lt;span class="p"&gt;],&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then you can reference the config like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/mail/send&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;support&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Incredible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is an incredible test message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or via index (in which case you do not need the &lt;code&gt;name&lt;/code&gt; property):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$axios&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;/mail/send&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// resolves to 'support'&lt;/span&gt;
  &lt;span class="na"&gt;from&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;John Doe&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;subject&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Incredible&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;text&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;This is an incredible test message&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's basically it, I hope that this is of use for some of you.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;You can use the module to easily setup email sending capabilities. If you plan to build a bigger SaaS that sends a lot of emails, an async solution that does the sending via a cronjob or via server-side hooks is probably a better idea. But for a first-off solution, it should work fine.&lt;/p&gt;




&lt;p&gt;Let me know what you think about the module and if there are any open questions. Also, since this is my first post, let me know what you think about the post in general.&lt;/p&gt;

&lt;p&gt;You can find the module &lt;a href="https://github.com/dword-design/nuxt-mail"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you like what I'm doing, follow me on &lt;a href="https://twitter.com/seblandwehr"&gt;Twitter&lt;/a&gt; or check out my &lt;a href="https://sebastianlandwehr.com"&gt;website&lt;/a&gt;. Also consider donating at &lt;a href="https://www.buymeacoffee.com/dword"&gt;Buy Me a Coffee&lt;/a&gt;, &lt;a href="https://www.paypal.com/paypalme/SebastianLandwehr"&gt;PayPal&lt;/a&gt; or &lt;a href="https://www.patreon.com/dworddesign"&gt;Patreon&lt;/a&gt;. Thank you so much! ❤️&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>nuxt</category>
      <category>vue</category>
      <category>javascript</category>
      <category>node</category>
    </item>
  </channel>
</rss>
