<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/">
    <channel>
        <title>Front-Commerce Developers Blog</title>
        <link>https://developers.front-commerce.com/blog</link>
        <description>Front-Commerce Developers Blog</description>
        <lastBuildDate>Fri, 08 Dec 2023 08:00:00 GMT</lastBuildDate>
        <docs>https://validator.w3.org/feed/docs/rss2.html</docs>
        <generator>https://github.com/jpmonette/feed</generator>
        <language>en</language>
        <item>
            <title><![CDATA[Dynamic page implementation: a side-by-side comparison]]></title>
            <link>https://developers.front-commerce.com/blog/2023-advent-calendar/08-dynamic-page-implementation-a-side-by-side-comparison</link>
            <guid>https://developers.front-commerce.com/blog/2023-advent-calendar/08-dynamic-page-implementation-a-side-by-side-comparison</guid>
            <pubDate>Fri, 08 Dec 2023 08:00:00 GMT</pubDate>
            <description><![CDATA[Discover the differences in dynamic page implementation between Front-Commerce 2.x and 3.x. Explore the transition from file-based routing and Enhancers in 2.x to Remix routes and loader functions in 3.x.]]></description>
            <content:encoded><![CDATA[<p>In today's article, we'll compare how dynamic page implementation differs
between Front-Commerce 2.x and Front-Commerce 3.x.</p>
<p>A dynamic page is generated on the fly when a user requests it, rather than
being statically generated at build time. This is particularly useful for pages
that rely on external data, such as product pages, category pages, or search
pages. For this article, we are going to use an FAQ Article detail as an
example.</p>
<p>This article aims to shed light on one of the most significant changes we've
made in Front-Commerce 3.x, making it easier for you to understand.</p>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Developer Guide series</div><div class="admonitionContent_TPdy"><p>This article is part of
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">our Developer Guide series</a>.
We're publishing new articles every month. <strong>Stay tuned!</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="2x-file-based-routing-enhancers-and-page-components">2.x: file-based routing, Enhancers and Page components<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/08-dynamic-page-implementation-a-side-by-side-comparison#2x-file-based-routing-enhancers-and-page-components" class="hash-link" aria-label="Direct link to 2.x: file-based routing, Enhancers and Page components" title="Direct link to 2.x: file-based routing, Enhancers and Page components" translate="no">​</a></h2>
<p>In Front-Commerce 2.x, dynamic pages were implemented using core components from
Front-Commerce.</p>
<p>This included <strong>file-based routing</strong>, which was implemented by Front-Commerce
itself on top of React Router. This allowed developers to map the rendered
component to a specific URL by creating a file in the <code>web/theme/routes/</code>.</p>
<div class="language-jsx codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_FMcr">web/theme/routes/faq/[slug].js</div><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-jsx codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// The route file was almost empty and only used to declare the Page component</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">FaqDetails</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"theme/pages/FaqDetails"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">default</span><span class="token plain"> </span><span class="token maybe-class-name">FaqDetails</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>The <strong>Page component</strong> was responsible for fetching data from the GraphQL API
and rendering the page once all the required data was available.</p>
<div class="language-jsx codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_FMcr">web/theme/pages/FaqDetails.js</div><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-jsx codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">React</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"react"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">Link</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"theme/components/atoms/Typography/Link"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">EnhanceFaqDetails</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./EnhanceFaqDetails"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token constant" style="color:#36acaa">H1</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"theme/components/atoms/Typography/Heading"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">VoteWidget</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"theme/modules/Faq/VoteWidget"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">Wysiwyg</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"theme/modules/WysiwygV2"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function maybe-class-name" style="color:#d73a49">FaqDetails</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">props</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> slug </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> props</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">match</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">params</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">slug</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword control-flow" style="color:#00009f">return</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">className</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">container</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag class-name" style="color:#00009f">Link</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">to</span><span class="token tag attr-value punctuation attr-equals" style="color:#393A34">=</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag attr-value" style="color:#e3116c">/faq</span><span class="token tag attr-value punctuation" style="color:#393A34">"</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text">⬅️ Back to list</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag class-name" style="color:#00009f">Link</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">br</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">        Slug: </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">slug</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">      </span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">      </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">props</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">loading</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">p</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text">Loading…</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">p</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">      </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">props</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">faqEntry</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">          </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag class-name" style="color:#00009f">H1</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">props</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">faqEntry</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">question</span><span class="token punctuation" style="color:#393A34">}</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag class-name" style="color:#00009f">H1</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">          </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag class-name" style="color:#00009f">Wysiwyg</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">content</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript" style="color:#00009f">props</span><span class="token tag script language-javascript punctuation" style="color:#393A34">.</span><span class="token tag script language-javascript property-access" style="color:#00009f">faqEntry</span><span class="token tag script language-javascript punctuation" style="color:#393A34">.</span><span class="token tag script language-javascript property-access" style="color:#00009f">answer</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">          </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag class-name" style="color:#00009f">VoteWidget</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">faqEntry</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript" style="color:#00009f">props</span><span class="token tag script language-javascript punctuation" style="color:#393A34">.</span><span class="token tag script language-javascript property-access" style="color:#00009f">faqEntry</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">        </span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain-text"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain-text">    </span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">default</span><span class="token plain"> </span><span class="token function maybe-class-name" style="color:#d73a49">EnhanceFaqDetails</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">FaqDetails</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Pages delegated the fetching of data to <strong>Enhancers</strong>
(<abbr title="Higher-Order Components">HOCs</abbr>), which were responsible for
retrieving data from the GraphQL API and handling rendering states before
feeding it to the Page component.</p>
<div class="language-jsx codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_FMcr">web/theme/pages/EnhanceFaqDetails.js</div><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-jsx codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// The Enhancer was responsible for fetching data and handling rendering states</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">graphqlWithPreload</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"web/core/apollo/graphqlWithPreload"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">compose</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"recompose/compose"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">FaqDetailsQuery</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./FaqDetailsQuery.gql"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">withEntityNotFound</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"theme/modules/PageError/NotFound/withEntityNotFound"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">default</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">compose</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">graphqlWithPreload</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">FaqDetailsQuery</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function-variable function" style="color:#d73a49">options</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">props</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">variables</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">slug</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> props</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">match</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">params</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">slug</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function-variable function" style="color:#d73a49">preloadOptions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">args</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">variables</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">        </span><span class="token literal-property property" style="color:#36acaa">slug</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> args</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">match</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">params</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">slug</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function-variable function" style="color:#d73a49">props</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter punctuation" style="color:#393A34">{</span><span class="token parameter"> data </span><span class="token parameter punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">loading</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">loading</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">error</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">loading</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">error</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">faqEntry</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">!</span><span class="token plain">data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">loading</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> data</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">faqGetBySlug</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// It could also be combined with other Enhancers</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// such as Loadable for a full page loading state</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// Loadable((props) =&gt; !props.loading, LoadingComponent),</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token function" style="color:#d73a49">withEntityNotFound</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token function-variable function" style="color:#d73a49">isFound</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token parameter">props</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> props</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">loading</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">||</span><span class="token plain"> props</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">faqEntry</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>Enhancers HOCs had several responsibilities and could combine different HOCs
from Front-Commerce to achieve the desired result.</p>
<p>For instance, they could combine <code>graphqlWithPreload</code> for fetching data with
preloading, <code>withEntityNotFound</code> and <code>Loadable</code> for handling different rendering
states. User restricted pages could leverage <code>checkAuth</code> for checking user
authentication and redirecting to the login page if necessary.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="plain-remix-routes-in-3x">Plain Remix routes in 3.x!<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/08-dynamic-page-implementation-a-side-by-side-comparison#plain-remix-routes-in-3x" class="hash-link" aria-label="Direct link to Plain Remix routes in 3.x!" title="Direct link to Plain Remix routes in 3.x!" translate="no">​</a></h2>
<p>In Front-Commerce 3.x, dynamic pages are implemented using a different approach:
we've replaced our custom file-based routing with
<a href="https://remix.run/docs/en/main/discussion/routes" target="_blank" rel="noopener noreferrer" class="">Remix routes</a>.</p>
<p>Remix routes now have more responsibilities than 2.x routes. They export a
<code>loader</code> function that is responsible for fetching data from the GraphQL API and
passing it to the Page component (main export of the route).</p>
<p>Route loaders can also be used to handle errors (with the <code>ErrorBoundary</code>
export), redirections (with the <code>redirect</code> response) and many other checks.
<strong>Routes code is usually simpler to reason about than Enhancers</strong>, with less
indirections.</p>
<p>Here is an example of a route that fetches a question from the GraphQL API and
renders it using a <code>&lt;FaqDetail /&gt;</code> Page component (that is a plain React
component). As you can see, all the logic belongs to the route!</p>
<div class="language-tsx codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_FMcr">app/routes/_main.faq.$slug.tsx</div><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-tsx codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token comment" style="color:#999988;font-style:italic">// The route is now a .tsx file, which allows us to use TypeScript and JSX syntax.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> json </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@front-commerce/remix/node"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> useLoaderData </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@front-commerce/remix/react"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">type</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token maybe-class-name">LoaderFunctionArgs</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@remix-run/node"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports maybe-class-name">FaqDetail</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"theme/pages/FaqDetail"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> isRouteErrorResponse</span><span class="token imports punctuation" style="color:#393A34">,</span><span class="token imports"> useRouteError </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@remix-run/react"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">FaqDetailDocument</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"~/graphql/graphql"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> </span><span class="token imports maybe-class-name">FrontCommerceApp</span><span class="token imports"> </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@front-commerce/remix"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// The route exports a `loader` function that is responsible</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// for fetching data and throwing errors, ensuring that</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// the main component is only rendered in the "happy path".</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">loader</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">async</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> context</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> params </span><span class="token punctuation" style="color:#393A34">}</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token maybe-class-name">LoaderFunctionArgs</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> slug </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> params</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// The `loader` uses the `FrontCommerceApp` class to access the Front-Commerce</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// core from Remix. In this example, we use it to fetch data from the GraphQL</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// unified API (similar to the one you're used to).</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> app </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">FrontCommerceApp</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">context</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">frontCommerce</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> response </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">await</span><span class="token plain"> app</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">graphql</span><span class="token punctuation" style="color:#393A34">.</span><span class="token method function property-access" style="color:#d73a49">query</span><span class="token punctuation" style="color:#393A34">(</span><span class="token maybe-class-name">FaqDetailDocument</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> slug </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token operator" style="color:#393A34">!</span><span class="token plain">response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">faqEntry</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">throw</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">new</span><span class="token plain"> </span><span class="token class-name">Response</span><span class="token punctuation" style="color:#393A34">(</span><span class="token string" style="color:#e3116c">"Question not found"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> status</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">404</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">json</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    question</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> response</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">faqEntry</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// The main component is a plain React component that receives</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// the data from the loader, using Remix fetching primitives (`useLoaderData`)</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// both on the server and on the client.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">default</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> question </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token generic-function function" style="color:#d73a49">useLoaderData</span><span class="token generic-function generic class-name operator" style="color:#393A34">&lt;</span><span class="token generic-function generic class-name keyword" style="color:#00009f">typeof</span><span class="token generic-function generic class-name"> loader</span><span class="token generic-function generic class-name operator" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag class-name" style="color:#00009f">FaqDetail</span><span class="token tag" style="color:#00009f"> </span><span class="token tag attr-name" style="color:#00a4db">question</span><span class="token tag script language-javascript script-punctuation punctuation" style="color:#393A34">=</span><span class="token tag script language-javascript punctuation" style="color:#393A34">{</span><span class="token tag script language-javascript" style="color:#00009f">question</span><span class="token tag script language-javascript punctuation" style="color:#393A34">}</span><span class="token tag" style="color:#00009f"> </span><span class="token tag punctuation" style="color:#393A34">/&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// The route also exports an ErrorBoundary component that is responsible</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic">// for displaying errors. It can be used to display a custom error page.</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> </span><span class="token function-variable function" style="color:#d73a49">ErrorBoundary</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token arrow operator" style="color:#393A34">=&gt;</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">const</span><span class="token plain"> error </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">useRouteError</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token keyword" style="color:#00009f">if</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">(</span><span class="token function" style="color:#d73a49">isRouteErrorResponse</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">error</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">)</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token keyword" style="color:#00009f">return</span><span class="token plain"> </span><span class="token tag punctuation" style="color:#393A34">&lt;</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token plain-text">FAQ : question not found</span><span class="token tag punctuation" style="color:#393A34">&lt;/</span><span class="token tag" style="color:#00009f">div</span><span class="token tag punctuation" style="color:#393A34">&gt;</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="conclusion">Conclusion<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/08-dynamic-page-implementation-a-side-by-side-comparison#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>We hope this article helped you understand how dynamic pages are implemented in
Front-Commerce 2.x and 3.x.</p>
<p>Here is a table comparing the different concepts between 2.x and 3.x:</p>
<table><thead><tr><th>Concept</th><th>Front-Commerce&nbsp;2.x</th><th>Front-Commerce&nbsp;3.x</th></tr></thead><tbody><tr><td>Page components</td><td>Plain React components (JSX)</td><td>Plain React components (JSX/TSX)</td></tr><tr><td>Routes</td><td>Custom file-based routing</td><td>Remix routes</td></tr><tr><td>Data fetching</td><td>Enhancers HOCs with Apollo</td><td><code>loader</code> functions with <code>FrontCommerceApp</code></td></tr><tr><td>Error Handling</td><td>Enhancers HOCs</td><td><code>ErrorBoundary</code> component</td></tr></tbody></table>
<p>We've made several changes to make it easier for you to build your projects. You
can now use Remix routes in a natural way, while still leveraging the power of
Front-Commerce with a cleaner separation of concerns.</p>
<p>Join us again for the next article in our
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">Developer Guide series!</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Front-Commerce 2 vs 3: a cleaner, more powerful configuration file]]></title>
            <link>https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file</link>
            <guid>https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file</guid>
            <pubDate>Thu, 07 Dec 2023 08:00:00 GMT</pubDate>
            <description><![CDATA[As developers, we're no strangers to the crucial role configuration files play in our applications. In this blog post, we will explore the differences between configuration between Front-Commerce 2.x and 3.x.]]></description>
            <content:encoded><![CDATA[<p>As developers, we're no strangers to the crucial role configuration files play
in our applications. They serve as the backbone, defining the behavior and
structure of our systems. In this article, we'll dive into the transformative
journey of configuration files in Front-Commerce, making a big leap from v2 to
v3.</p>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Developer Guide series</div><div class="admonitionContent_TPdy"><p>This article is part of
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">our Developer Guide series</a>.
We're publishing new articles all year. <strong>Stay tuned!</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="front-commerce-2x-navigating-the-configuration-maze">Front-Commerce 2.x: Navigating the Configuration Maze<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file#front-commerce-2x-navigating-the-configuration-maze" class="hash-link" aria-label="Direct link to Front-Commerce 2.x: Navigating the Configuration Maze" title="Direct link to Front-Commerce 2.x: Navigating the Configuration Maze" translate="no">​</a></h2>
<p>In Front-Commerce 2.x, configuring your application was not really as intuitive
as it was the result of several iterations over time. While the configuration
file played a central role, certain aspects raised concerns:</p>
<ul>
<li class=""><strong>Unclear naming conventions</strong>: The usage of names like webModules, modules,
and serverModules in the configuration file introduced ambiguity, making it
less intuitive for developers to discern their purposes.</li>
<li class=""><strong>Distributed configuration files</strong>: Configuration settings were spread across
various files in <code>src/config</code>, leading to a decentralized structure. This
distribution added complexity, making it harder to manage and maintain a
holistic view of the application's configuration.</li>
<li class=""><strong>Dynamic configuration needs</strong>: Different modules necessitated separate
configurations, extending beyond the main configuration files. This diversity
in configuration areas, such as Content Security Policies (CSP) or having to
install separated npm packages with specific versions, added an additional
layer of intricacy for developers to navigate.</li>
<li class=""><strong>Overrides challenges</strong>: Some "Extension components", such as
<code>getAdditionalDataComponent</code> for Payment and Shipping methods, were designed
specifically for to be overridden when installing modules.</li>
</ul>
<p>Here's a snippet of how configuration file (<strong><code>front-commerce.js</code></strong>) looked like
in 2.x:</p>
<div class="language-jsx codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-jsx codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token plain">module</span><span class="token punctuation" style="color:#393A34">.</span><span class="token property-access">exports</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Front Commerce DEV"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">url</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"http://www.front-commerce.test"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">modules</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"./modules/datasource-elasticsearch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"./theme-chocolatine"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token string" style="color:#e3116c">"./modules/front-commerce-b2b"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">serverModules</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"FrontCommerce"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">path</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"server/modules/front-commerce"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Elasticsearch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">      </span><span class="token literal-property property" style="color:#36acaa">path</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"datasource-elasticsearch/server/modules/magento2-elasticsearch"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Magento2"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">path</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"server/modules/magento2"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Magento2GraphQL"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">path</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"server/modules/magento2-graphql"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Magento2Commerce"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">path</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"server/modules/magento2-commerce"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Magento2B2B"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">path</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"front-commerce-b2b/server/modules/magento2"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token literal-property property" style="color:#36acaa">webModules</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"FrontCommerce"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">path</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./src/web"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Theme Chocolatine"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">path</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./theme-chocolatine/web"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">name</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"FrontCommerce B2B"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token literal-property property" style="color:#36acaa">path</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./modules/front-commerce-b2b/web"</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>While it served its purpose, these challenges paved the way for a more
streamlined and user-friendly approach in subsequent versions.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="front-commerce-3x-an-unified-simplified-configuration-file">Front-Commerce 3.x: An unified, simplified configuration file<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file#front-commerce-3x-an-unified-simplified-configuration-file" class="hash-link" aria-label="Direct link to Front-Commerce 3.x: An unified, simplified configuration file" title="Direct link to Front-Commerce 3.x: An unified, simplified configuration file" translate="no">​</a></h2>
<p>Fast forward to v3, and we've completely refactored how a Front-Commerce app
configuration was defined. The configuration is now made through a single file,
<code>front-commerce.config.js</code>, which includes all the necessary information for
running a Front-Commerce app. Let's break down the key enhancements.</p>
<div class="language-tsx codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-tsx codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> defineConfig </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@front-commerce/core/config"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">themeChocolatine</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@front-commerce/theme-chocolatine"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">magento2</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@front-commerce/magento2"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">adobeB2B</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@front-commerce/adobe-b2b"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">storesConfig</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./app/config/stores"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">cacheConfig</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./app/config/caching"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">appCSPProvider</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./app/config/cspProvider"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword" style="color:#00009f">default</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">defineConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  extensions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token function" style="color:#d73a49">themeChocolatine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">magento2</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"> storesConfig </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">adobeB2B</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  stores</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> storesConfig</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  cache</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> cacheConfig</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  configuration</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    providers</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token function" style="color:#d73a49">appCSPProvider</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  v2_compat</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    useApolloClientQueries</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    useFormsy</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">true</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  pwa</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    appName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Front-Commerce"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    shortName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"Front-Commerce"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    description</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"My e-commerce application"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    themeColor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"#fbb03b"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    icon</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"assets/icon.png"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">    maskableIcon</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"assets/icon.png"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="single-source-of-truth">Single Source of Truth<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file#single-source-of-truth" class="hash-link" aria-label="Direct link to Single Source of Truth" title="Direct link to Single Source of Truth" translate="no">​</a></h3>
<p>In contrast to v2, the v3 configuration file is now the single endpoint for all
things application-related. All extensions are registered through this file like
before, but it now also features the various configuration previously found in
<code>src/config/*.js</code> files, such as stores and caching configuration. This makes
using the configuration details much more reliable in the app.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="typing-with-typescript">Typing with TypeScript<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file#typing-with-typescript" class="hash-link" aria-label="Direct link to Typing with TypeScript" title="Direct link to Typing with TypeScript" translate="no">​</a></h3>
<p>Leveling up the developer experience, the v3 configuration file is now fully
typed using TypeScript. Autocomplete and type checking bring a greater level of
clarity and confidence when writing your app’s configuration, while also giving
a quick sneak peek of each extension features and customizations.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="extension-api">Extension API<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file#extension-api" class="hash-link" aria-label="Direct link to Extension API" title="Direct link to Extension API" translate="no">​</a></h3>
<p>As said above, v2’s “modules” have evolved into "extensions" in v3. Their
registration is now a eased through a simplified extension API
(<code>defineExtension()</code> and <code>defineRemixExtension()</code>) which streamlines the process
and makes your application more modular and extensible. Each extension can
directly define their own needs so that their usage is simplified in
<code>front-commerce.config.js</code></p>
<p>This subject however deserves a whole article to be written about it
— *<strong>*stay tuned**</strong> 👀.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="themes">Themes<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file#themes" class="hash-link" aria-label="Direct link to Themes" title="Direct link to Themes" translate="no">​</a></h3>
<p>Theme overrides, once defined via <code>webModules</code>, are now an integral part of the
configuration. Registering them becomes as straightforward as any other
extension, streamlining the overall architecture, and further reducing the main
configuration file responsibilities.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="no-more-use-of-srcconfigjs">No more use of <code>src/config/*.js</code><a href="https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file#no-more-use-of-srcconfigjs" class="hash-link" aria-label="Direct link to no-more-use-of-srcconfigjs" title="Direct link to no-more-use-of-srcconfigjs" translate="no">​</a></h3>
<p>V3 eliminates the need for separate configuration files (<code>src/config/*.js</code>) for
stores and caching. Previously, those files were imported and used by components
all over the codebase. Now, those are directly included in
<code>front-commerce.config.js</code>, promoting a cleaner and more organized setup. This
configuration is accessible through a shared “config” that is available in all
key location in the code.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="embracing-the-change">Embracing the change<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file#embracing-the-change" class="hash-link" aria-label="Direct link to Embracing the change" title="Direct link to Embracing the change" translate="no">​</a></h2>
<p>The transition from V2 to V3 marks a paradigm shift in how we approach
configuration. With a consolidated and type-safe configuration file, we are
confident developers can embrace a more efficient and enjoyable development
experience. In upcoming version, further specific extension points will be added
to complete our “configuration arsenal”, and make it even better than before.</p>
<p>Please let us now what you think about this, and stay tuned for the
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">Front-Commerce Advent Calendar</a>’s
next article!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[PWA Stack: from manual to automated asset generation]]></title>
            <link>https://developers.front-commerce.com/blog/2023-advent-calendar/06-pwa-stack-from-manual-to-automated-asset-generation</link>
            <guid>https://developers.front-commerce.com/blog/2023-advent-calendar/06-pwa-stack-from-manual-to-automated-asset-generation</guid>
            <pubDate>Wed, 06 Dec 2023 08:00:00 GMT</pubDate>
            <description><![CDATA[Progressive Web Applications (PWAs) are a way to deliver fast, reliable, and engaging user experiences on the web. In this blog post, we will explore the evolution of managing a “PWA Stack”, from its manual asset generation approach in Front-Commerce 2.x to the streamlined and automated process introduced in Front-Commerce 3.x.]]></description>
            <content:encoded><![CDATA[<p>Progressive Web Applications (PWAs) are a way to deliver fast, reliable, and
engaging user experiences on the web.</p>
<p>In Front-Commerce, we’ve always ensured that every applications could be turned
into a PWA to improve the user experience. To achieve this, developers can rely
on standard web features and technologies that we name “the PWA Stack”.
Front-Commerce acts as a technical enabler to ease the lives of developers to
create and maintain this stack.</p>
<p>In this blog post, we will explore the evolution of this “PWA Stack”, from its
manual asset generation approach in Front-Commerce 2.x to the streamlined and
automated process introduced in Front-Commerce 3.x.</p>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Developer guide series</div><div class="admonitionContent_TPdy"><p>This article is part of
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">our Developer Guide series</a>.
We're publishing new articles all year. <strong>Stay tuned!</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="what-does-the-pwa-stack-consist-of">What does the PWA Stack consist of?<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/06-pwa-stack-from-manual-to-automated-asset-generation#what-does-the-pwa-stack-consist-of" class="hash-link" aria-label="Direct link to What does the PWA Stack consist of?" title="Direct link to What does the PWA Stack consist of?" translate="no">​</a></h2>
<p>The PWA Stack, is our term to describe the different assets, technologies and
practices turning websites into web applications with native app-like
capabilities.</p>
<p>A PWA is built on the principles of progressive enhancement and web standards.
It provides the ability to a website for being installed and run on various
devices. <strong>The stack consists of three main components: the manifest, service
workers, and app shell.</strong></p>
<p><strong>The manifest is a JSON file</strong> that describes the application and its behavior,
including details such as the name, icons, start URL, and display mode.<br>
<strong>Service workers are scripts that run in the background</strong> and enable features
such as offline access, push notifications, and background
synchronization.<br> <strong>The app shell is the minimal HTML, CSS, and
JavaScript</strong> needed to power the user interface when the application is
launched.</p>
<p>These components must be combined together to create reliable, fast, and
engaging web experiences that are accessible to all users, regardless of their
device or network conditions.</p>
<p>In Front-Commerce, <strong>the PWA Stack empowers developers to generate and register
these components in a cohesive way</strong> so they can have a minimal setup working
out-of-the box, so they can focus on developing code adapting the user
experience to match their specific needs (or stick with the default minimal PWA
setup).</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="2x-a-default-pwa-stack-to-override">2.x: a default PWA Stack to override<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/06-pwa-stack-from-manual-to-automated-asset-generation#2x-a-default-pwa-stack-to-override" class="hash-link" aria-label="Direct link to 2.x: a default PWA Stack to override" title="Direct link to 2.x: a default PWA Stack to override" translate="no">​</a></h2>
<p>In Front-Commerce 2.x, the process of generating PWA assets is ready when
starting a project. It however requires manual customization by integrators and
developers.</p>
<p>Developers must override the <code>manifest.json</code> and <code>app-shell.html</code> in their
project and modify its content to match their project, including the name,
short_name, colors, and icons. While this provide flexibility, it also introduce
complexity and the potential for human error.</p>
<p>One common pitfall is that <strong>developers often forgot to customize the PWA assets
entirely or partially</strong>, leading to a generic and less effective PWA
implementation when going live (hopefully we detect this when auditing the site,
but it can then be forgotten or not prioritized).</p>
<p>Another problem we found over time, is that developers don’t necessarily want to
invest in advanced customization or don’t understand clearly each of these
components responsibilities. <strong>It could lead to partially working experiences.</strong></p>
<p>We provided guidance on how to customize the PWA Stack components provided by
Front-Commerce to ensure that the website is recognized as a Progressive Web
Application (PWA), but as any guide … it doesn’t enforce anything!</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="3x-simplicity-first">3.x: simplicity first<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/06-pwa-stack-from-manual-to-automated-asset-generation#3x-simplicity-first" class="hash-link" aria-label="Direct link to 3.x: simplicity first" title="Direct link to 3.x: simplicity first" translate="no">​</a></h2>
<p>In Front-Commerce 3.x, we approached the PWA Stack in a different way.</p>
<p>We focused on providing a simple and efficient way for integrators to describe
the PWA Stack with metadata, and for Front-Commerce to derive all the required
stack automatically.</p>
<p>This approach not only reduces the burden on integrators and developers but also
ensures consistency and adherence to PWA best practices.</p>
<p>Technically, you will adapt the following configuration in your
<code>front-commerce.config.ts</code> configuration file.</p>
<div class="language-typescript codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_FMcr">front-commerce.config.ts</div><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-typescript codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports punctuation" style="color:#393A34">{</span><span class="token imports"> defineConfig </span><span class="token imports punctuation" style="color:#393A34">}</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@front-commerce/core/config"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">import</span><span class="token plain"> </span><span class="token imports">themeChocolatine</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">from</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"@front-commerce/theme-chocolatine"</span><span class="token punctuation" style="color:#393A34">;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token keyword module" style="color:#00009f">export</span><span class="token plain"> </span><span class="token keyword module" style="color:#00009f">default</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">defineConfig</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  extensions</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">[</span><span class="token function" style="color:#d73a49">themeChocolatine</span><span class="token punctuation" style="color:#393A34">(</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">]</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token comment" style="color:#999988;font-style:italic">// […]</span><span class="token plain"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">  pwa</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">    appName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ACME Store"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">    shortName</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"ACME Store"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">    themeColor</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"#fbb03b"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">    icon</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"public/pwa-icon.png"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">    maskableIcon</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"public/pwa-masked-icon"</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">    cacheTTLInMs</span><span class="token operator" style="color:#393A34">:</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">7</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">24</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">60</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">*</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">1000</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line theme-code-block-highlighted-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">,</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token punctuation" style="color:#393A34">}</span><span class="token punctuation" style="color:#393A34">)</span><span class="token punctuation" style="color:#393A34">;</span><br></div></code></pre></div></div>
<p>It only takes a few minutes to define, then Front-Commerce takes care of
generating all assets required for your PWA Stack consistently.</p>
<p>The PWA assets are generated in adherence to best practices and include all
different icon variations in the manifest, so each device can use the most
adapted to their specifications.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="advanced-customization">Advanced customization<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/06-pwa-stack-from-manual-to-automated-asset-generation#advanced-customization" class="hash-link" aria-label="Direct link to Advanced customization" title="Direct link to Advanced customization" translate="no">​</a></h2>
<p>While the default PWA Stack is sufficient for most projects, we also want to
provide more advanced customization options for developers who want to go
further.</p>
<p>In Remix, routes are a great abstraction over the network layer. They allow to
describe the data requirements for a given page, and could be used in the
context of a PWA to provide a fallback when the data is not available. That's
the goal of the <a href="https://remix-pwa.run/" target="_blank" rel="noopener noreferrer" class="">Remix PWA</a> project.<br> In
Front-Commerce 3.x, our PWA Stack is using Remix PWA under the hook, but doesn't
expose extension points for you to leverage its full power yet.</p>
<p>We're looking for your feedback and use cases to help us prioritize the next
steps. Please reach out to us if you have specific PWA use cases in mind!</p>
<p>Join us again for the next article in our
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">Developer Guide series!</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[We're launching on Product Hunt! 🚀]]></title>
            <link>https://developers.front-commerce.com/blog/2023-advent-calendar/05-launching-on-product-hunt</link>
            <guid>https://developers.front-commerce.com/blog/2023-advent-calendar/05-launching-on-product-hunt</guid>
            <pubDate>Tue, 05 Dec 2023 08:00:00 GMT</pubDate>
            <description><![CDATA[We're launching Front-Commerce v3 on Product Hunt. Please support us by upvoting Front-Commerce and sharing it with your network. Here is a step-by-step guide explaining how to upvote us!]]></description>
            <content:encoded><![CDATA[<p>Today is a special day! <strong>We need each one of you to help us make it a
success.</strong></p>
<p>We're launching Front-Commerce v3 on Product Hunt. Please support us by upvoting
Front-Commerce and sharing it with your network.</p>
<p>This launch aims to introduce Front-Commerce to a broader audience, especially
those who are not yet familiar with our product.</p>
<p>Read more for a step-by-step guide explaining how to upvote. <strong>It will take less
than 1 minute!</strong></p>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Developer Guide series</div><div class="admonitionContent_TPdy"><p>This article is part of
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">our Developer Guide series</a>.
We're publishing a new articles all year. <strong>Stay tuned!</strong></p></div></div>
<p>We're so grateful that you're interested in upvoting our launch on Product Hunt.
It’s really important for us.</p>
<p>Here's a step-by-step guide to help you through the process:</p>
<ol>
<li class="">Head over to
<a href="https://www.producthunt.com/posts/front-commerce-3-0" target="_blank" rel="noopener noreferrer" class="">our Product Hunt “Front-Commerce 3.0” launch page</a></li>
<li class="">Click on the upvote button. <img decoding="async" loading="lazy" alt="Upvote button" src="https://developers.front-commerce.com/assets/images/05-upvote-button-6bc64aaa54ec0f8ed29f896cbd442101.png" width="927" height="473" class="img_Gx30"></li>
<li class="">You'll then be prompted to log in or create an account if not already logged
it. <strong>You can use your Google, Twitter or LinkedIn account for a quick
signup.</strong> <img decoding="async" loading="lazy" alt="Login or signup" src="https://developers.front-commerce.com/assets/images/05-login-signup-266726c4680bbe1abc061720abe1c382.png" width="544" height="409" class="img_Gx30"></li>
<li class="">⚠️ After logging in, <strong>click on the upvote button again</strong> 🤷. This time, your
vote will be recorded and added to the product's total score near the
<strong>UPVOTED</strong> button. <img decoding="async" loading="lazy" alt="Upvote button when upvoted" src="https://developers.front-commerce.com/assets/images/05-upvoted-6e8986078d900a70fcb9dd4707ce0a21.png" width="895" height="445" class="img_Gx30"></li>
<li class="">Congratulations! You've successfully upvoted our launch on Product Hunt. Your
vote helps the product gain more visibility, and could potentially lead to
more users and customers.</li>
<li class=""><strong>Bonus:</strong> Spread the word!<!-- -->
<ul>
<li class="">Share this article in your open space, on Slack communities you’re part of,</li>
<li class=""><a href="https://twitter.com/Front_Commerce/status/1731953598433472591" target="_blank" rel="noopener noreferrer" class="">Retweet us on X</a></li>
<li class="">Share our announcement on LinkedIn</li>
</ul>
</li>
</ol>
<p>Thank you for being a part of the Front-Commerce community. Keep up the great
work! 🎉</p>
<p>Join us again for the next article in our
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">Developer Guide series!</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Remix extended for Composable Commerce]]></title>
            <link>https://developers.front-commerce.com/blog/2023-advent-calendar/04-remix-extended-for-composable-commerce</link>
            <guid>https://developers.front-commerce.com/blog/2023-advent-calendar/04-remix-extended-for-composable-commerce</guid>
            <pubDate>Mon, 04 Dec 2023 08:00:00 GMT</pubDate>
            <description><![CDATA[In today’s article, we’ll explain how Front-Commerce extends Remix to incorporate all the features built since 2016 while empowering developers with more autonomy.]]></description>
            <content:encoded><![CDATA[<p>Since 2016, Front-Commerce has been dedicated to supporting teams that operate
in the Headless and Composable commerce space. Being among the first
Frontend-as-a-service providers presented us with its unique challenges, but we
have built solid foundations over the years.</p>
<p>Now, with Front-Commerce v3, we are excited to bring all our experience from the
past seven years to the Remix ecosystem.</p>
<p>Read more to discover how Front-Commerce extends Remix to incorporate all the
features available in Front-Commerce v2.</p>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Developer Guide series</div><div class="admonitionContent_TPdy"><p>This article is part of
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">our Developer Guide series</a>.
We're publishing a new articles all year. <strong>Stay tuned!</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="front-commerce-2x-the-all-inclusive-solution">Front-Commerce 2.x: the “all-inclusive” solution<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/04-remix-extended-for-composable-commerce#front-commerce-2x-the-all-inclusive-solution" class="hash-link" aria-label="Direct link to Front-Commerce 2.x: the “all-inclusive” solution" title="Direct link to Front-Commerce 2.x: the “all-inclusive” solution" translate="no">​</a></h2>
<p>When Front-Commerce was created, React and GraphQL were still evolving with
limited frameworks for developers to use. Most of the ecosystem relied on Create
React App for client-side rendered applications or Gatsby for static site
generation.</p>
<p>Our team understood that <strong>server-side rendering was a more accurate option for
eCommerce storefronts</strong>, which is why we made it a core feature of
Front-Commerce.</p>
<p>With the release of Front-Commerce 2.x, we integrated all the necessary features
you would need into the core: from bundling and server-side rendering, to
routing and HTTP caching.</p>
<p>To illustrate, the components of a Front-Commerce 2.x app look like this:</p>
<p><a href="https://developers.front-commerce.com/assets/files/04-FC_2.x_components-d313282e5ac7bd42a3735f900b3c3741.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Front-Commerce 2.x components" src="https://developers.front-commerce.com/assets/images/04-FC_2.x_components-d313282e5ac7bd42a3735f900b3c3741.png" width="1344" height="518" class="img_Gx30"></a></p>
<p>Key highlights of a Front-Commerce 2.x:</p>
<ul>
<li class="">Front-Commerce must be an Express.js Node application.</li>
<li class="">During server-side rendering (SSR), developers can only use Front-Commerce's
extension points to access server-side-rendered data.</li>
<li class="">Front-Commerce only supports the addition of Express middlewares at specific
extension points.</li>
<li class="">Hydration is managed by Front-Commerce with some restrictions such as
inability to register global React context providers</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="front-commerce-3x-leveraging-remix">Front-Commerce 3.x: leveraging Remix<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/04-remix-extended-for-composable-commerce#front-commerce-3x-leveraging-remix" class="hash-link" aria-label="Direct link to Front-Commerce 3.x: leveraging Remix" title="Direct link to Front-Commerce 3.x: leveraging Remix" translate="no">​</a></h2>
<p>Fast-forwarding to 2023, the industry has seen the emergence of several stable
and popular frameworks, with Next.js and Remix at the forefront. After careful
consideration,
<a class="" href="https://developers.front-commerce.com/changelog/front-commerce-is-getting-a-remix">we decided to adopt Remix for several reasons previously outlined in another article</a>.</p>
<p>Our priority has always been to ensure that the development experience with
Front-Commerce is seamless and <strong>consistent with how these technologies can be
used outside of Front-Commerce</strong>. This approach not only ensures that agencies
can efficiently onboard new developers, but also guarantees that projects
developed with Front-Commerce are future-proof and can evolve with the industry.</p>
<p>To achieve this, we've made a fundamental change: <strong>we made Front-Commerce
usable in any standard Remix applications</strong>. This is a change for developers
familiar with Front-Commerce 2.x, but it means that developers have more freedom
and autonomy.</p>
<p>In short: <strong>you own your Remix application, Front-Commerce brings the batteries
powering your composable storefront.</strong></p>
<p>Technically, the components of a Front-Commerce 3.x app look like this:</p>
<p><a href="https://developers.front-commerce.com/assets/files/04-FC_3.x_components-9a5d1383d07f6e453eaafe551392a873.png" target="_blank" class=""><img decoding="async" loading="lazy" alt="Front-Commerce 3.x components in a Remix application" src="https://developers.front-commerce.com/assets/images/04-FC_3.x_components-9a5d1383d07f6e453eaafe551392a873.png" width="1521" height="806" class="img_Gx30"></a></p>
<p>Key points to take away from this:</p>
<ul>
<li class="">Your application is based on a standard Remix app.</li>
<li class="">Launch your application using Front-Commerce's CLI, which takes care of
running additional tools such as GraphQL Codegen, Sass compilation,
TypeScript, and more.</li>
<li class="">Front-Commerce provides additional features such as Extensions, theme
management, configuration, and GraphQL unified schema.</li>
<li class="">To initialize Front-Commerce, certain key components such as Remix’s
<code>server.ts</code> must bootstrap it.</li>
<li class="">You interact with a <code>FrontCommerceApp</code> from your loaders and actions to use
Front-Commerce.</li>
<li class="">The skeleton contains a boilerplate: it is completely transparent when
creating a new application.</li>
<li class="">Currently, Front-Commerce only supports <code>@remix-run/express</code>, but it has been
designed to be easily portable to other deployment targets (Cloudflare,
Netlify, Vercel, etc.) in the future.</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="how-do-you-feel-about-this">How do you feel about this?<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/04-remix-extended-for-composable-commerce#how-do-you-feel-about-this" class="hash-link" aria-label="Direct link to How do you feel about this?" title="Direct link to How do you feel about this?" translate="no">​</a></h2>
<p>We’re aware that it may not be totally clear for you yet. We recommend to keep
this in mind while reading the rest of our Advent Calendar Series that will dive
into each component, and provide practical examples of using every
Front-Commerce feature in a Remix application.</p>
<p>If you have any questions or concerns, <strong>feel free to keep the conversation
going: we’ll be happy to answer!</strong></p>
<p>Join us again for the next article in our
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">Developer Guide series!</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How-to create a new Front-Commerce project?]]></title>
            <link>https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project</link>
            <guid>https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project</guid>
            <pubDate>Sun, 03 Dec 2023 08:00:00 GMT</pubDate>
            <description><![CDATA[In today’s article, we’ll explain how we made the process of starting a new project as smooth as possible, so you could start from a fresh, minimal state within seconds.]]></description>
            <content:encoded><![CDATA[<p>Starting from scratch is always exciting for a developer!</p>
<p>Creating new Front-Commerce projects quickly has endless advantages: build a
minimal reproduction case for reporting issues, quickly test solutions, explain
concepts to colleagues, or prototype for potential customers.</p>
<p>In this article we’ll explain how we made this process as smooth as possible, so
you could start from a fresh, minimal state within seconds.</p>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Developer Guide series</div><div class="admonitionContent_TPdy"><p>This article is part of
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">our Developer Guide series</a>.
We're publishing new articles all year. <strong>Stay tuned!</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="the-importance-of-a-starting-point">The importance of a starting point<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project#the-importance-of-a-starting-point" class="hash-link" aria-label="Direct link to The importance of a starting point" title="Direct link to The importance of a starting point" translate="no">​</a></h2>
<p>When we started working on Front-Commerce, we wanted to make sure that starting
a new project would be as easy as possible.<br> <strong>We made a deliberate choice
to offer a "starter" project</strong> containing all the essential boilerplate code
needed to launch a fully functional Front-Commerce application locally.</p>
<p>The maintenance of this project presents several challenges, which may not be
immediately apparent:</p>
<ul>
<li class="">have a good DX (this is the first impression newcomers will have of
Front-Commerce),</li>
<li class="">keep it up-to-date with the latest versions of Front-Commerce and
dependencies,</li>
<li class="">find the right balance (amount of code) between<!-- -->
<ul>
<li class="">a good starting point with many examples for newcomers,</li>
<li class="">as minimal as possible so new long-term projects don't have to remove
unnecessary code.</li>
</ul>
</li>
<li class="">convenient to use in different scenarios (workshops, demos, examples,
reproduction cases, etc.)</li>
</ul>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="2x-with-the-skeleton-repository">2.x: with the <code>skeleton</code> repository<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project#2x-with-the-skeleton-repository" class="hash-link" aria-label="Direct link to 2x-with-the-skeleton-repository" title="Direct link to 2x-with-the-skeleton-repository" translate="no">​</a></h2>
<p>In Front-Commerce 2.x, we have introduced a
<a href="https://gitlab.blackswift.cloud/front-commerce/front-commerce-skeleton" target="_blank" rel="noopener noreferrer" class=""><code>skeleton</code></a>
repository, which serves as a foundational Front-Commerce project pre-configured
for a Magento2 setup.</p>
<p>Developers can clone the git repository, update specific configurations with
their Magento2 instance information, and they are good to go!<br>For
connecting a different stack, additional changes are required. <em>Read our
<a class="" href="https://developers.front-commerce.com/docs/2.x/essentials/installation">2.x installation guide</a> for the exact
steps.</em></p>
<p>Recognizing the need for <strong>tangible and actionable examples</strong>,
<a href="https://github.com/front-commerce/examples" target="_blank" rel="noopener noreferrer" class="">we have launched a new <code>examples</code> repository.</a><br>
These example modules can be seamlessly integrated into a Front-Commerce's
skeleton project, demonstrating practical applications of concepts outlined in
our documentation.</p>
<p>The use of the <code>skeleton</code> and <code>examples</code> repositories has become increasingly
prevalent in our support activities, offering a more effective means of
illustrating concepts through concrete examples.<br> This approach has also
proven to be more user-friendly and has evolved into a mechanism for generating
<strong>short-lived reproduction cases when reporting a bug</strong>.</p>
<div class="theme-admonition theme-admonition-note admonition_epGf alert alert--secondary"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M6.3 5.69a.942.942 0 0 1-.28-.7c0-.28.09-.52.28-.7.19-.18.42-.28.7-.28.28 0 .52.09.7.28.18.19.28.42.28.7 0 .28-.09.52-.28.7a1 1 0 0 1-.7.3c-.28 0-.52-.11-.7-.3zM8 7.99c-.02-.25-.11-.48-.31-.69-.2-.19-.42-.3-.69-.31H6c-.27.02-.48.13-.69.31-.2.2-.3.44-.31.69h1v3c.02.27.11.5.31.69.2.2.42.31.69.31h1c.27 0 .48-.11.69-.31.2-.19.3-.42.31-.69H8V7.98v.01zM7 2.3c-3.14 0-5.7 2.54-5.7 5.68 0 3.14 2.56 5.7 5.7 5.7s5.7-2.55 5.7-5.7c0-3.15-2.56-5.69-5.7-5.69v.01zM7 .98c3.86 0 7 3.14 7 7s-3.14 7-7 7-7-3.12-7-7 3.14-7 7-7z"></path></svg></span>Aside: our internal <code>demos</code> repository</div><div class="admonitionContent_TPdy"><p>Internally, we also have a <code>demos</code> repository, which contains the configurations
and modules used for all our public demos (Magento2, Adobe B2B, Magento1 and
BigCommerce).<br> The demos you can find on our website are actually skeletons
configured with content from this repository. For instance, our Magento2 demo
uses our Contentful (CMS), Cloudinary (Images) and Lyra (Payment) modules.<br>
With some workarounds, <strong>we can deploy a preview demo on each of our Merge
Request</strong> on Front-Commerce Cloud, to ensure that a feature or a bugfix is
working as expected … so we're also big users of our skeleton!</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="3x-with-the-create-remix-cli-command">3.x: with the <code>create-remix</code> CLI command<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project#3x-with-the-create-remix-cli-command" class="hash-link" aria-label="Direct link to 3x-with-the-create-remix-cli-command" title="Direct link to 3x-with-the-create-remix-cli-command" translate="no">​</a></h2>
<p>In Front-Commerce 3.x, we have reevaluated and redefined our approach, driven by
two primary objectives:</p>
<ol>
<li class=""><strong>Simplified project initiation</strong>: it should take less than 30 seconds to
start a new project from scratch, with a minimal configuration</li>
<li class=""><strong>Unified use cases</strong>: we want to use a consistent process for both our
internal use cases and our users, unifying the experience across the board.</li>
</ol>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="front-commerces-skeleton-is-a-remix-stack">Front-Commerce's skeleton is a Remix Stack<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project#front-commerces-skeleton-is-a-remix-stack" class="hash-link" aria-label="Direct link to Front-Commerce's skeleton is a Remix Stack" title="Direct link to Front-Commerce's skeleton is a Remix Stack" translate="no">​</a></h3>
<p>Front-Commerce 3.x is built on <a href="https://remix.run/" target="_blank" rel="noopener noreferrer" class="">Remix</a>, you know this!<br>
Remix is a framework that provides
<a href="https://remix.run/docs/en/main/other-api/create-remix#create-remix" target="_blank" rel="noopener noreferrer" class="">a CLI command to create new projects</a>,
called <code>create-remix</code>.</p>
<p>Naturally we decided to embrace the Remix way of doing things, and we turned our
skeleton into a <em>Remix Stack</em>.<br> A Remix Stack is a Remix project that can
be used as a <strong>template for <code>create-remix</code></strong>.</p>
<p>Launching a new Front-Commerce 3.x project from scratch should be as
straightforward as running:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token plain">npx create-remix hello-front-commerce </span><span class="token parameter variable" style="color:#36acaa">--template</span><span class="token plain"> https://new.front-commerce.app/</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token comment" style="color:#999988;font-style:italic"># or with pnpm</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token function" style="color:#d73a49">pnpm</span><span class="token plain"> dlx create-remix hello-front-commerce </span><span class="token parameter variable" style="color:#36acaa">--template</span><span class="token plain"> https://new.front-commerce.app/</span><br></div></code></pre></div></div>
<p><strong>Please follow our detailed
<a class="" href="https://developers.front-commerce.com/docs/3.x/get-started/installation">Installation page</a></strong> if you want to try it
out.</p>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Transition period</div><div class="admonitionContent_TPdy"><p>We're currently in a transition period, where we still are using some
<code>@front-commerce/compat</code> packages in our default theme.<br> For this reason,
the <code>create-remix</code> command must be prefixed with
<code>NPM_CONFIG_LEGACY_PEER_DEPS=true</code> at the date of writing.</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="a-minimal-mode">A "minimal" mode<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project#a-minimal-mode" class="hash-link" aria-label="Direct link to A &quot;minimal&quot; mode" title="Direct link to A &quot;minimal&quot; mode" translate="no">​</a></h3>
<p>For technical reasons (and design flaws), it was not possible to start a
Front-Commerce application without a remote service in 2.x.<br> We reworked
our core to make it possible in 3.x. We call this mode the "minimal" mode, as it
doesn't require any remote service.</p>
<p>This mode is <strong>perfect for evaluation purposes, workshops, and for creating
reproduction cases when reporting an issue or testing an idea</strong>.</p>
<p>Technically, a "minimal" Front-Commerce application is an application with a
single extension: <code>@front-commerce/theme-chocolatine</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="the-skeleton-is-now-part-of-front-commerces-repository">The <code>skeleton</code> is now part of Front-Commerce's repository<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project#the-skeleton-is-now-part-of-front-commerces-repository" class="hash-link" aria-label="Direct link to the-skeleton-is-now-part-of-front-commerces-repository" title="Direct link to the-skeleton-is-now-part-of-front-commerces-repository" translate="no">​</a></h3>
<p>If you want to find the code of our skeleton, you can find it
<a href="https://gitlab.blackswift.cloud/front-commerce/front-commerce/-/tree/main/skeleton?ref_type=heads" target="_blank" rel="noopener noreferrer" class="">in our main repository</a>.</p>
<p>We decided to move it there for several reasons:</p>
<ul>
<li class="">it's easier for us to maintain, as its code can be updated in the same
changeset as Front-Commerce's code</li>
<li class="">it allows us to use the same code than our users when working on core features</li>
<li class="">it makes our core repository a standard Front-Commerce project repository,
deployable on Front-Commerce Cloud without any special treatment</li>
</ul>
<p>It has no impact whatsoever on our users, but we find it interesting to share
this information with you: we're dogfooding our own product in a better way now!
😉</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="examples-and-demos-are-also-part-of-the-skeleton">Examples and demos are also part of the skeleton<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project#examples-and-demos-are-also-part-of-the-skeleton" class="hash-link" aria-label="Direct link to Examples and demos are also part of the skeleton" title="Direct link to Examples and demos are also part of the skeleton" translate="no">​</a></h3>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Feedback wanted</div><div class="admonitionContent_TPdy"><p>We're still not sure about this one, and we'd love to have your feedback on this
move.</p></div></div>
<p>As of writing, we have reorganized the code for our demos under the skeleton
directory, and a similar transition is underway for our examples.</p>
<p>In Front-Commerce 3.x, a notable feature is <strong>the ability to package everything
as an extension</strong>. Leveraging this functionality, we have encapsulated our
examples and demos as extensions, housed in the <code>./example-extensions</code>
subdirectory of the skeleton.</p>
<p>When initiating a new project, you can enable any of these extension by
registering them in the <code>front-commerce.config.ts</code> file.<br> For those
embarking on a new "long-term" project, the extra-step of removing the
<code>./example-extensions</code> directory will set you on the right path.</p>
<p>Our rationale behind this approach is that the ability to swiftly run a demo or
example locally far outweighs the trade-off of having additional code in the
skeleton.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="whats-next">What’s next?<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project#whats-next" class="hash-link" aria-label="Direct link to What’s next?" title="Direct link to What’s next?" translate="no">​</a></h2>
<p>We're still working on improving the experience of starting a new project, and
want to ensure that it fits <strong>your use cases</strong>.</p>
<p>In the pipeline, we are gearing up to introduce the following changes:</p>
<ul>
<li class="">an installation CLI with prompts to help you configure it initially (register
and install the extensions you want to use, populate the <code>.env</code> file, etc.)</li>
<li class="">migration of all our examples to Front-Commerce 3.x.</li>
<li class="">increased utilization of minimal reproduction cases during support
interactions.</li>
</ul>
<p>❓ <strong>We would greatly appreciate your input on the following:</strong></p>
<ul>
<li class="">what additions would you like to see in the skeleton?</li>
<li class="">how can we further reduce friction in your daily use cases?</li>
<li class="">are you interested in a "Fake store" extension that populates your local
storefront with sample products, categories, etc.?</li>
</ul>
<p>Join us again for the next article in our
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">Developer Guide series!</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Front-Commerce: your project’s dependency]]></title>
            <link>https://developers.front-commerce.com/blog/2023-advent-calendar/02-front-commerce-your-projects-dependency</link>
            <guid>https://developers.front-commerce.com/blog/2023-advent-calendar/02-front-commerce-your-projects-dependency</guid>
            <pubDate>Sat, 02 Dec 2023 08:00:00 GMT</pubDate>
            <description><![CDATA[In today’s article, we’ll explain why we switched from a single Git dependency to several npm packages from a private registry.]]></description>
            <content:encoded><![CDATA[<p>Front-Commerce serves as an important npm dependency in your e-commerce project,
allowing you to update it as per your requirement. To ensure its seamless
operation, we suggest adopting the following upgrade approach: <strong>semi-automated
for patch versions and scheduled (2-3 times a year) for minor versions.</strong></p>
<p>In today’s article, we’ll explain why we switched from a single Git dependency
to several npm packages from a private registry.</p>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Developer Guide series</div><div class="admonitionContent_TPdy"><p>This article is part of
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">our Developer Guide series</a>.
We're publishing new articles all year. <strong>Stay tuned!</strong></p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="2x-a-single-git-dependency">2.x: a single Git dependency<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/02-front-commerce-your-projects-dependency#2x-a-single-git-dependency" class="hash-link" aria-label="Direct link to 2.x: a single Git dependency" title="Direct link to 2.x: a single Git dependency" translate="no">​</a></h2>
<p>In a Front-Commerce 2.x project, the core is distributed as a single Git
dependency. To install or update it, use the following command:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">npm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> git+ssh://git@gitlab.blackswift.cloud/front-commerce/front-commerce.git</span><span class="token comment" style="color:#999988;font-style:italic">#2.27.0</span><br></div></code></pre></div></div>
<p>You get all the code, directly from our private Git repository. While this
approach may seem convenient and straightforward, it comes with some drawbacks:</p>
<ul>
<li class=""><strong>SSH Access Setup:</strong> Setting up SSH access to our private repository,
including in your Docker development stack and CI environment, can be a source
of misunderstanding and frustration for your team.</li>
<li class=""><strong>Unnecessary Code:</strong> You receive all the code, even the portions you don't
use, which can be confusing when browsing the codebase.</li>
<li class=""><strong>Unnecessary Dependencies:</strong> You also get all the dependencies of modules you
don't use, potentially leading to conflicts with your application dependencies
and increasing the size of your <code>node_modules</code> and project folder.</li>
</ul>
<p>This approach also has <strong>direct engineering consequences</strong> in the way the code
is designed and released.</p>
<p>For instance, we have to rely on our own patterns and conventions to expose a
public API.<br> In 2.x, developers can use almost any internal module
(resolvers, factories, adapters…). Even if an exported class or function was
designed for internal use in a first place, we have to be very careful about
breaking changes when we wanted to refactor it.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="3x-transition-to-a-set-of-npm-packages">3.x: transition to a set of npm packages<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/02-front-commerce-your-projects-dependency#3x-transition-to-a-set-of-npm-packages" class="hash-link" aria-label="Direct link to 3.x: transition to a set of npm packages" title="Direct link to 3.x: transition to a set of npm packages" translate="no">​</a></h2>
<p>In Front-Commerce 3.x, we have transitioned to a set of npm packages, which are
now published on a private GitLab registry. To install or update these packages,
use the following command:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">npm</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> @front-commerce/core@3.1.1</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="authentication">Authentication<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/02-front-commerce-your-projects-dependency#authentication" class="hash-link" aria-label="Direct link to Authentication" title="Direct link to Authentication" translate="no">​</a></h3>
<p>Instead of using SSH, you can employ any
<a href="https://docs.gitlab.com/ee/user/packages/npm_registry/#install-a-package" target="_blank" rel="noopener noreferrer" class="">private registry technique</a>
to install the packages. For instance, you can use a <code>.npmrc</code> file:</p>
<div class="language-ini codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockTitle_FMcr">~/.npmrc</div><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-ini codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token plain">//gitlab.blackswift.cloud/api/v4/projects/24/packages/npm/:_authToken=&lt;your_gitlab_token&gt;</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">@front-commerce:registry=https://gitlab.blackswift.cloud/api/v4/projects/24/packages/npm/</span><br></div></code></pre></div></div>
<div class="theme-admonition theme-admonition-tip admonition_epGf alert alert--success"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>Our recommendation</div><div class="admonitionContent_TPdy"><p>We recommend the use of a global <code>~/.npmrc</code> file for each developer, where you
can store an authentication token. This approach ensures that every
<code>@front-commerce/*</code> package will be installed from the private registry for
every project.</p></div></div>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="modularized-packages">Modularized Packages<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/02-front-commerce-your-projects-dependency#modularized-packages" class="hash-link" aria-label="Direct link to Modularized Packages" title="Direct link to Modularized Packages" translate="no">​</a></h3>
<p>The core has been restructured into several distinct packages, each serving a
specific purpose:</p>
<ul>
<li class=""><strong><code>@front-commerce/core</code></strong>: the fundamental elements of Front-Commerce,
including the GraphQL API, React components, Configuration, Caching, and more,
as known from 2.x.</li>
<li class=""><strong><code>@front-commerce/remix</code></strong>: provides low-level adapters and public API for
accessing <code>@front-commerce/core</code> features in a standard Remix project (<em>more
details on this later this month 😉</em>)</li>
<li class=""><strong><code>@front-commerce/compat</code></strong>: offers a compatibility layer that enables the
use of 2.x features and removed APIs in a 3.x project, ensuring a seamless and
progressive transition.</li>
<li class=""><strong><code>@front-commerce/theme-chocolatine</code></strong>: serves as our base theme, featuring a
fully-equipped storefront with a set of React components and styles to build
upon.</li>
<li class=""><strong>All other packages are features, packaged as Front-Commerce Extensions.</strong>
These can be selectively chosen and combined based on your project's specific
requirements. Examples include:<!-- -->
<ul>
<li class=""><code>@front-commerce/adobe-b2b</code>,</li>
<li class=""><code>@front-commerce/algolia</code>,</li>
<li class=""><code>@front-commerce/contentful</code>,</li>
<li class=""><code>@front-commerce/magento2</code>,</li>
<li class=""><code>@front-commerce/paypal</code>,</li>
<li class="">etc.</li>
</ul>
</li>
</ul>
<p><strong>All packages are versioned in unison</strong> and align with our Front-Commerce
versioning.<br> We decided to bump the version number for every release, even
in the absence of change in the package. This approach facilitates easy
identification of the Front-Commerce version used in your project and simplifies
communication about it.</p>
<p>Similar to the process in 2.x, you can update all <code>@front-commerce/*</code> packages
simultaneously.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="advantages">Advantages<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/02-front-commerce-your-projects-dependency#advantages" class="hash-link" aria-label="Direct link to Advantages" title="Direct link to Advantages" translate="no">​</a></h3>
<p>This new approach offers several benefits:</p>
<ul>
<li class=""><strong>It matches the way you work</strong> with other dependencies in your projects.</li>
<li class=""><strong>Package exports are explicit</strong>, exposing only what is intended for external
use. This clarity makes it easier to discover what's here for you to use and
enables us to provide better backward compatibility guarantees.</li>
<li class="">You will install only the necessary components, <strong>avoiding unnecessary
bloat</strong>.</li>
</ul>
<p>To illustrate this last point, let's compare the size of a Front-Commerce 2.x
<code>node_modules</code> folder with a 3.x one, on our Magento2 demo project:</p>
<ul>
<li class="">Front-Commerce 2.x: <strong>1.3 GB</strong></li>
<li class="">Front-Commerce 3.x: <strong>321 MB</strong> 🎉</li>
</ul>
<p>We hope you'll enjoy this new approach as much as we do! We eagerly await your
feedback.</p>
<p>Join us again for the next article in our
<a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series">Developer Guide series!</a></p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[🎉 Introducing the Front-Commerce Developer Guide series! 🎉]]></title>
            <link>https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series</link>
            <guid>https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series</guid>
            <pubDate>Fri, 01 Dec 2023 08:00:00 GMT</pubDate>
            <description><![CDATA[We're happy to announce that we'll be sharing with you some actionable insights about Front-Commerce this year!]]></description>
            <content:encoded><![CDATA[<p>We're happy to announce that we'll be sharing actionable insights with you about
Front-Commerce!</p>
<p>As we get into 2024, we wanted to take a moment to reflect on our most important
release so far: <strong>Front-Commerce Remixed!</strong></p>
<p><a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series"><img decoding="async" loading="lazy" alt="Developer Guide: Front-Commerce 2 vs. 3" src="https://developers.front-commerce.com/assets/images/Developer_guide_1-608c2192182604dbb05bbab8c93e2f75.png" width="1200" height="627" class="img_Gx30"></a></p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="lets-dive-in">Let’s dive in!<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series#lets-dive-in" class="hash-link" aria-label="Direct link to Let’s dive in!" title="Direct link to Let’s dive in!" translate="no">​</a></h2>
<p>In these series, we’ll break down specific development tasks tackled in
Front-Commerce projects. We’ll compare how it was done in 2.x, and its
counterpart in the present, so we can all learn and grow together.</p>
<p>Over the years, we've gained valuable insight into how our product can better
serve our users. As we introduced new features and more projects and teams were
providing feedback, we noticed some recurring themes.</p>
<p>We recognize that developers are continually seeking ways to streamline their
workflow and improve their development process. That's what drove our vision for
the changes we brought in Front-Commerce Remixed.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="a-series-made-for-you">A series made for you!<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series#a-series-made-for-you" class="hash-link" aria-label="Direct link to A series made for you!" title="Direct link to A series made for you!" translate="no">​</a></h2>
<p><strong>Small, easy to digest, knowledge bites even when you're on the go.</strong> Regular
new articles that can fit into the busiest of workdays. Keep track of all the
articles in this series by referring to the index we've provided below (we’ll
keep it up-to-date):</p>
<ol>
<li class="">🎉 Introducing the Front-Commerce Developer Guide series! 🎉 <em>(you're reading
it!)</em></li>
<li class=""><a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/02-front-commerce-your-projects-dependency">Front-Commerce: your project’s dependency</a></li>
<li class=""><a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/03-how-to-create-a-new-front-commerce-project">How-to create a new Front-Commerce project?</a></li>
<li class=""><a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/04-remix-extended-for-composable-commerce">Remix extended for Composable Commerce</a></li>
<li class=""><a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/05-launching-on-product-hunt">We're launching on Product Hunt! 🚀</a></li>
<li class=""><a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/06-pwa-stack-from-manual-to-automated-asset-generation">PWA Stack: from manual to automated asset generation</a></li>
<li class=""><a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/07-a-cleaner-more-powerful-configuration-file">Front-Commerce 2 vs 3: a cleaner, more powerful configuration file</a></li>
<li class=""><a class="" href="https://developers.front-commerce.com/blog/2023-advent-calendar/08-dynamic-page-implementation-a-side-by-side-comparison">Dynamic page implementation: a side-by-side comparison</a></li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="we-value-your-feedback">We Value Your Feedback!<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series#we-value-your-feedback" class="hash-link" aria-label="Direct link to We Value Your Feedback!" title="Direct link to We Value Your Feedback!" translate="no">​</a></h2>
<p>From the entire FC team, we want to say thank you for your continued support and
feedback that has helped us to create and continuously refine the best possible
product for developers and merchants.</p>
<p><strong>Let’s make it a conversation! 🗣️</strong><br> Your thoughts and feedback on these
articles, new APIs, or features are always welcome. We're eager to chat and
listen to your ideas and suggestions. Don't hesitate to <strong>share your thoughts
with us on Slack, support channels or email</strong>. We're in this together!</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="stay-tuned">Stay tuned!<a href="https://developers.front-commerce.com/blog/2023-advent-calendar/01-introducing-the-front-commerce-advent-calendar-series#stay-tuned" class="hash-link" aria-label="Direct link to Stay tuned!" title="Direct link to Stay tuned!" translate="no">​</a></h2>
<p>Stay tuned for tomorrow's post, where we'll start diving into concrete changes
between Front-Commerce versions 2.x and 3.x.</p>
<p>Follow us on <a href="https://twitter.com/front_commerce" target="_blank" rel="noopener noreferrer" class="">Twitter</a>,
<a href="https://www.linkedin.com/company/front-commerce/posts/" target="_blank" rel="noopener noreferrer" class="">LinkedIn</a> or subscribe
to <a href="https://developers.front-commerce.com/blog/rss.xml" target="_blank" rel="noopener noreferrer" class="">our RSS feed</a> (simple and efficient!) so you don’t
miss an article.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Audits conducted in Front-Commerce for client projects]]></title>
            <link>https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects</link>
            <guid>https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects</guid>
            <pubDate>Fri, 11 Aug 2023 12:00:00 GMT</pubDate>
            <description><![CDATA[When it comes to developing an e-commerce website, there are many different]]></description>
            <content:encoded><![CDATA[<p>When it comes to developing an e-commerce website, there are many different
areas that require constant attention. Project teams may introduce performance
issues or forget important features that could negatively impact the user
experience. That's why audits are crucial to ensure that the website is meeting
high standards and delivering a great user experience.</p>
<p>At Front-Commerce, we conduct thorough audits on our client projects and provide
recommendations to improve website performance and user experience. In this blog
post, we will discuss the key points we measure during our audits.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-performance">🚀 Performance<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-performance" class="hash-link" aria-label="Direct link to 🚀 Performance" title="Direct link to 🚀 Performance" translate="no">​</a></h2>
<p>Performance is a critical factor in the success of an e-commerce store. A slow
website can lead to frustrated customers and lost sales. During our audits, we
measure the performance of our client's websites in two key areas: server and
webperfs.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="server">Server<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#server" class="hash-link" aria-label="Direct link to Server" title="Direct link to Server" translate="no">​</a></h3>
<p>During our audits, we check if the website's server is performing well. We make
sure that things like cache and data loaders are implemented correctly to
improve server performance. We also verify if the cache strategies are properly
implemented to
<a href="https://developers.front-commerce.com/blog/audit-optimization-number-of-external-requests" target="_blank" rel="noopener noreferrer" class="">reduce the number of requests made to external services</a>.
Another thing we check is that the server-side rendering (SSR) is implemented
properly to improve the <abbr title="Time To First Byte">TTFB</abbr>. We also
ensure that there are no memory leaks that can negatively impact the
application's stability.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="webperfs">Webperfs<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#webperfs" class="hash-link" aria-label="Direct link to Webperfs" title="Direct link to Webperfs" translate="no">​</a></h3>
<p></p><p>Another important part of our performance audit is the<!-- --> <!-- -->
<abbr title="Web Performance">webperfs</abbr> analysis. webperfs measures the
website speed, responsiveness, and overall user experience. This includes
checking if the website's fonts and images are optimized for the store and if
the JavaScript bundle size is at an optimal level. We also check if important
pages are preloaded to improve the perceived performance for end users.</p><p></p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-theme-customization">🎨 Theme customization<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-theme-customization" class="hash-link" aria-label="Direct link to 🎨 Theme customization" title="Direct link to 🎨 Theme customization" translate="no">​</a></h2>
<p>We understand that every e-commerce store has unique branding requirements.
During our audits, we check if the website's theme has been customized to match
the client's branding guidelines. We also ensure that any customizations do not
negatively impact the website's performance or user experience.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-accessibility">🦻 Accessibility<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-accessibility" class="hash-link" aria-label="Direct link to 🦻 Accessibility" title="Direct link to 🦻 Accessibility" translate="no">​</a></h2>
<p>We believe that all websites should be accessible to everyone, regardless of
their abilities. During our audits, we check if the website meets accessibility
standards, such as having proper alt tags for images, keyboard navigation
support, and proper contrast ratios.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="️-styleguide">🖌️ Styleguide<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#%EF%B8%8F-styleguide" class="hash-link" aria-label="Direct link to 🖌️ Styleguide" title="Direct link to 🖌️ Styleguide" translate="no">​</a></h2>
<p>Consistency is key when it comes to creating a great user experience. During our
audits, we check if the website's style guide is consistent throughout the
website. We also ensure that the website's typography, colors, and spacing are
in line with the client's branding guidelines.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-links-received-by-e-mail">📨 Links received by e-mail<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-links-received-by-e-mail" class="hash-link" aria-label="Direct link to 📨 Links received by e-mail" title="Direct link to 📨 Links received by e-mail" translate="no">​</a></h2>
<p>A customer journey extends beyond the web UI and encompasses email interactions.
That is why we also check the links that are received by email, as it ensures
that customers can access the correct pages of the website, leading to a better
overall user experience.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-audit-broken-links-in-the-store">🔗 Audit broken links in the store<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-audit-broken-links-in-the-store" class="hash-link" aria-label="Direct link to 🔗 Audit broken links in the store" title="Direct link to 🔗 Audit broken links in the store" translate="no">​</a></h2>
<p>In a project, developers could have forgotten to update a hardcoded link, or
content writers may have contributed unfinished content or made typos. That's
why during our audits, we perform a thorough check for broken links and provide
recommendations to fix them, ensuring that the website's user experience and SEO
are not negatively impacted.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-seo">🔍 SEO<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-seo" class="hash-link" aria-label="Direct link to 🔍 SEO" title="Direct link to 🔍 SEO" translate="no">​</a></h2>
<p>Having good SEO is crucial to driving traffic to the website. During our audits,
we check for the following:</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="404--redirections">404 &amp; redirections<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#404--redirections" class="hash-link" aria-label="Direct link to 404 &amp; redirections" title="Direct link to 404 &amp; redirections" translate="no">​</a></h3>
<p>We check for any 404 errors and ensure that the website has proper redirections
in place. This is especially important when migrating to Front-Commerce from
another platform, as the links may not be in the same format. This can cause 404
errors for any pages previously crawled by search engine robots, such as Google.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="robotstxt">Robots.txt<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#robotstxt" class="hash-link" aria-label="Direct link to Robots.txt" title="Direct link to Robots.txt" translate="no">​</a></h3>
<p>We ensure that the website's robots.txt file is properly configured to allow
search engines to crawl the website's pages.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="sitemap">Sitemap<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#sitemap" class="hash-link" aria-label="Direct link to Sitemap" title="Direct link to Sitemap" translate="no">​</a></h3>
<p>We check if the website has a sitemap.xml file and that it is correctly
generated. More information about this can be found
<a href="https://developers.front-commerce.com/docs/2.x/advanced/production-ready/sitemap" target="_blank" rel="noopener noreferrer" class="">here</a></p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="meta-tags-and-microdata">Meta tags and microdata<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#meta-tags-and-microdata" class="hash-link" aria-label="Direct link to Meta tags and microdata" title="Direct link to Meta tags and microdata" translate="no">​</a></h3>
<p>We ensure that the website's meta tags and microdata are properly configured to
improve the website's search engine rankings and visibility when sharing on
social platforms.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-pwa-progressive-web-app">📱 PWA (Progressive Web App)<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-pwa-progressive-web-app" class="hash-link" aria-label="Direct link to 📱 PWA (Progressive Web App)" title="Direct link to 📱 PWA (Progressive Web App)" translate="no">​</a></h2>
<p>We ensure that the store meets the standards for a PWA. We provide
recommendations to improve the website's PWA capabilities.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-analytics">📈 Analytics<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-analytics" class="hash-link" aria-label="Direct link to 📈 Analytics" title="Direct link to 📈 Analytics" translate="no">​</a></h2>
<p>During our audits, we check if the website has proper analytics tracking in
place. This helps our clients to make data-driven decisions to improve their
website's performance and user experience. More information about this can be
found <a href="https://developers.front-commerce.com/docs/2.x/category/analytics" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-code-quality-audit">🧑‍💻 Code quality audit<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-code-quality-audit" class="hash-link" aria-label="Direct link to 🧑‍💻 Code quality audit" title="Direct link to 🧑‍💻 Code quality audit" translate="no">​</a></h2>
<p>Auditing code quality in a project is essential for several reasons. Firstly, it
helps identify and rectify potential bugs, vulnerabilities, and performance
issues, ensuring a more stable and secure application (as mentioned above).
Secondly, it promotes maintainability and ensures that the project can be
updated during its life. By adhering to Front-Commerce best practices,
developers can upgrade to newer Front-Commerce versions more easily and with
less risk of introducing bugs. Finally, our code quality audit encourages
consistent coding standards and improves overall code readability. This leads to
a more robust, efficient, and sustainable codebase.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-application-stability">🪄 Application stability<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-application-stability" class="hash-link" aria-label="Direct link to 🪄 Application stability" title="Direct link to 🪄 Application stability" translate="no">​</a></h2>
<p>Application stability is a crucial aspect of a composable architecture, like the
one used by Front-Commerce. It refers to the website's ability to remain
resilient to external systems outages, such as server downtime or configuration
errors. Ensuring stability is essential for a front-end solution like
Front-Commerce, as it directly impacts the user experience and the website's
ability to drive sales. Front-Commerce conducts thorough audits to identify
potential issues that could affect stability and provides recommendations to
improve resilience and ensure a reliable website.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="-magic-button">✨ Magic Button<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#-magic-button" class="hash-link" aria-label="Direct link to ✨ Magic Button" title="Direct link to ✨ Magic Button" translate="no">​</a></h2>
<p>We believe in going above and beyond for our clients. During our audits, we look
for opportunities to add additional features to the website that will improve
the contribution experience and improve the merchant’s team productivity. Our
<code>Magic Button</code> feature allows contributors to seamlessly improve the content on
the website with direct links to the content source. We ensure that the
contribution mode activation is secure and that any custom content is wrapped
with the <code>StorefrontContent</code> component. More information about this can be found
<a href="https://developers.front-commerce.com/docs/2.x/category/magic-button" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="️-prod-server--ci">☁️ Prod server &amp; CI<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#%EF%B8%8F-prod-server--ci" class="hash-link" aria-label="Direct link to ☁️ Prod server &amp; CI" title="Direct link to ☁️ Prod server &amp; CI" translate="no">​</a></h2>
<p>We check if the website is properly deployed to the production server and if the
continuous integration (CI) process is working correctly. This ensures that the
website is always up-to-date and running smoothly.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="️-audit-logs">🗒️ Audit logs<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#%EF%B8%8F-audit-logs" class="hash-link" aria-label="Direct link to 🗒️ Audit logs" title="Direct link to 🗒️ Audit logs" translate="no">​</a></h2>
<p>After conducting a thorough audit of the website, it's important to keep track
of any bugs or issues that may arise once the site is live. While we analyze the
codebase and test the application during the audit, we believe that analyzing
application logs and monitoring metrics is also crucial once the site is live.
This allows us to detect any smaller bugs or performance issues that may have
been missed during testing. We follow up on our audits with log analysis a few
days after the project is live to ensure that everything is running smoothly and
to address any issues that may arise. By addressing these smaller issues, we can
improve the overall quality of the application.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="️-checklist-before-production">☑️ Checklist before production<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#%EF%B8%8F-checklist-before-production" class="hash-link" aria-label="Direct link to ☑️ Checklist before production" title="Direct link to ☑️ Checklist before production" translate="no">​</a></h2>
<p>Before we proceed with the audit, we have a checklist that should ideally be
done by integrators in the project. This checklist includes items such as
verifying that the environment is properly configured, that the data has been
properly migrated, and that there are no broken links or missing assets. You can
find a detailed checklist in our documentation
<a href="https://developers.front-commerce.com/docs/2.x/advanced/production-ready/checklist-before-production" target="_blank" rel="noopener noreferrer" class="">here</a>.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="conclusion">Conclusion<a href="https://developers.front-commerce.com/blog/audits-conducted-in-front-commerce-for-client-projects#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>In summary, audits are essential for ensuring that e-commerce websites meet the
high standards necessary to drive sales and provide an exceptional user
experience. At Front-Commerce, we take great pride in conducting comprehensive
audits and providing our clients with actionable recommendations to enhance
their website's performance and user experience. By partnering with us, our
clients can rest assured that their website is optimized for success and
delivering the best possible experience for their customers.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Why do we check the number of external API calls in our audits?]]></title>
            <link>https://developers.front-commerce.com/blog/audit-optimization-number-of-external-requests</link>
            <guid>https://developers.front-commerce.com/blog/audit-optimization-number-of-external-requests</guid>
            <pubDate>Mon, 10 Jul 2023 17:55:00 GMT</pubDate>
            <description><![CDATA[On most of the projects built with Front-Commerce, we perform an audit. Without]]></description>
            <content:encoded><![CDATA[<p>On most of the projects built with Front-Commerce, we perform an audit. Without
surprise, these audits are conducted on the basis of a checklist. The first part
is devoted to performance and the very first criterion is to evaluate the number
of external requests necessary to build the most visited pages when everything
is cached. The point is to target zero external request to generate those pages.
Maybe you wonder why we check that or why we give it so much importance.</p>
<p>This <em>Performance</em> section is introduced with the following sentence:</p>
<blockquote>
<p>Performance is essential to improve user experience, but also to reduce server
load and thus increase the site's traffic capacity.</p>
</blockquote>
<p>So the point of the whole section is not only to increase the performances i.e.
in that case, the time it takes to generate a page but also to increase the
scalability of the application i.e.
<a href="https://en.wikipedia.org/wiki/Scalability" target="_blank" rel="noopener noreferrer" class="">according to Wikipedia</a>, <q>the
property of [the application] to handle a growing amount of work</q>.</p>
<p>To measure the number of external requests, you can use
<a class="" href="https://developers.front-commerce.com/docs/2.x/reference/environment-variables#debugging">one of our debug flags</a>.
For instance, here I'll use a very basic setup where Front-Commerce is connected
only to a Magento2 instance, so I can add <code>DEBUG=axios</code> in the environment to
have some information about external requests. Depending on your actual setup,
you might need other values to also count requests to Prismic or any other
external service.</p>
<p>Also, we are mainly interested in the most popular pages of the site. Commonly,
the homepage is most visited page. By default, we also check the category and
the product pages. Depending on your project, this list can be slightly
different.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="number-of-external-api-calls-versus-performance">Number of external API calls versus performance<a href="https://developers.front-commerce.com/blog/audit-optimization-number-of-external-requests#number-of-external-api-calls-versus-performance" class="hash-link" aria-label="Direct link to Number of external API calls versus performance" title="Direct link to Number of external API calls versus performance" translate="no">​</a></h2>
<p>Note: <em>Performance</em> is a very wide topic. By <em>performance</em> here, we are looking
at the time needed to generate a page server side. This is very easy to measure
with a <code>curl</code> based command:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token plain">$ </span><span class="token function" style="color:#d73a49">time</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-s</span><span class="token plain"> http://example.com/my/url </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> /dev/null</span><br></div></code></pre></div></div>
<p>On a Front-Commerce setup configured without cache and connected to a Magento2
instance, 27 requests to Magento2 APIs are needed to generate a category page.
Each of these requests takes a significant amount of time, sometimes several
hundred of milliseconds. While when caches are enabled, if everything is in
cache, no external request is made.</p>
<p>Without surprise, the time needed to generate the page is completely different:</p>
<ul>
<li class="">without cache, on my local setup, it took between 5 and 6 seconds;</li>
<li class="">with everything already cached, it took between 200 and 300 milliseconds.</li>
</ul>
<p>It's 20 times faster! The example is a bit extreme, but I guess you get the
point. Also, without external requests, the response time is somehow similar to
any external API call. This means that if on a page you have one external API
request left, getting rid of it might divide the response time by two. Worth a
try, don't you think?</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="number-of-external-api-calls-versus-scalability">Number of external API calls versus scalability<a href="https://developers.front-commerce.com/blog/audit-optimization-number-of-external-requests#number-of-external-api-calls-versus-scalability" class="hash-link" aria-label="Direct link to Number of external API calls versus scalability" title="Direct link to Number of external API calls versus scalability" translate="no">​</a></h2>
<p>Measuring the scalability is harder. It is done with load tests that involves
running some scenarios to simulate traffic peaks (usually inspired by past
events) in a production like environment. That's definitely not something you
can do reliably on your local environment in 10 minutes. That being said, we
always see a clear correlation between the number of external requests and the
scalability of the application.</p>
<p>Commonly, the target of those external requests (the Magento2 instance in my
previous example) becomes the bottleneck of the application especially if some
popular pages requires several API requests to the same service i.e. one page
generated by Front-Commerce entails <code>n</code> requests to one external service.</p>
<p>Depending on how Front-Commerce is hosted, it can also be the bottleneck because
it will be <em>busy</em> waiting for some APIs to reply 😀.</p>
<hr>
<p>The conclusion is simple: <strong>when it comes to external request, the less the
better</strong>. After having said that, it remains the hard work of optimizing the
application and the recipe is classic:</p>
<ol>
<li class="">is the external request strictly needed ? In some case, it might be an
opportunity to discover useless code or to discuss feature;</li>
<li class="">if it is strictly needed then you need to add more cache to the application
either
<a class="" href="https://developers.front-commerce.com/docs/2.x/advanced/graphql/dataloaders-and-cache-invalidation#what-are-dataloaders">by leveraging the dataloader mechanism</a>
or by using
<a class="" href="https://developers.front-commerce.com/docs/2.x/prismic/resolver-cache">the cache at resolver level if your project embeds content from Prismic</a>.</li>
</ol>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[VSCode Remote Development: Setup and usage]]></title>
            <link>https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage</link>
            <guid>https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage</guid>
            <pubDate>Tue, 02 May 2023 12:00:00 GMT</pubDate>
            <description><![CDATA[Every developer has their own preferences for their setup, whether it be]]></description>
            <content:encoded><![CDATA[<p>Every developer has their own preferences for their setup, whether it be
software or hardware. I’ve been a remote developer since 2018, and since then
I’ve tried various ways to organize my workspace at home, that would fit both my
work and personal times.</p>
<p>A typical remote developer kit will often include a laptop and one or more
monitors. In my case, because I already had a multi-monitor setup for my
personal desktop PC, all I needed was to come up with a way to homogenize and
make it work with the company’s provided laptop.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="my-current-setup-vs-code-remote-development">My current setup: <strong>VS Code Remote Development</strong><a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#my-current-setup-vs-code-remote-development" class="hash-link" aria-label="Direct link to my-current-setup-vs-code-remote-development" title="Direct link to my-current-setup-vs-code-remote-development" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="what-is-it-">What is it ?<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#what-is-it-" class="hash-link" aria-label="Direct link to What is it ?" title="Direct link to What is it ?" translate="no">​</a></h3>
<p><a href="https://code.visualstudio.com/docs/remote/remote-overview" target="_blank" rel="noopener noreferrer" class="">VS Code Remote Development</a>
is an extension pack for Microsoft’s widely used IDE VS Code. It allows
developers to “use a container, remote machine, or the&nbsp;Windows Subsystem for
Linux&nbsp;(WSL) as a full-featured development environment”. What it means, is that
you will have your source code located on a single place, and you will be able
to update it seamlessly from another system using VS Code.</p>
<p><em>Note: see our
<a href="https://developers.front-commerce.com/blog/wsl-development-environment" target="_blank" rel="noopener noreferrer" class="">blog post on installing a WSL development environment</a>
if you're interested.</em></p>
<p>The requirements are:</p>
<ul>
<li class="">For the client, pretty much anything capable of running VS Code <em>(with special
needs for containers for Microsoft Windows due to Docker’s own requirements)</em></li>
<li class="">For the host, a wide range of systems are supported. If you’re not using a
“mainstream” OS or distribution, you might want to check the requirements
section of the
<a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack" target="_blank" rel="noopener noreferrer" class="">extension pack’s Marketplace page</a>.</li>
</ul>
<p>In this blog post, we’ll only talk about the SSH connections, so you will need
to ensure that your host has an SSH Host set up. If you don’t, you can follow
<a href="https://code.visualstudio.com/docs/remote/troubleshooting#_installing-a-supported-ssh-server" target="_blank" rel="noopener noreferrer" class="">Microsoft’s guide on how to setup one</a>.
For example, on Ubuntu, you can the command
<code>sudo apt-get install openssh-server</code>.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="installation">Installation<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#installation" class="hash-link" aria-label="Direct link to Installation" title="Direct link to Installation" translate="no">​</a></h3>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>info</div><div class="admonitionContent_TPdy"><p>At the time of writing, this guides uses screenshots and instructions for VS
Code 1.78.0 and Remote Development 0.24.0.</p></div></div>
<p>That’s where this method shines.</p>
<p>The package installation on the client side is really simple: you’ll only have
to install the
<strong><a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack" target="_blank" rel="noopener noreferrer" class="">Remote Development</a></strong>
extension pack from Visual Studio Marketplace on your local machine’s VS Code.
This will provide your IDE with all needed extensions to work on your remote
environment.</p>
<p>Once that’s done, you will notice two new icons</p>
<ul>
<li class="">One in your Activity Bar (the vertical bar on the left of VS Code) which is
the “Remote Explorer”. Clicking on it will reveal the explorer’s sidebar, in
which where you will be able to see your different connections.</li>
</ul>
<p><img decoding="async" loading="lazy" alt="Remote Explorer" src="https://developers.front-commerce.com/assets/images/RemoteExplorer-2aae02362a1af881950ebe7dca1d2cfe.png" width="340" height="639" class="img_Gx30"></p>
<ul>
<li class="">One in the left of your Status bar (the horizontal bar at the very bottom of
VS Code’s window), which will display what host the current window is
“attached” to.</li>
</ul>
<p><img decoding="async" loading="lazy" alt="Remote Development icon" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEUAAAA7CAYAAAAtpUeYAAAKEklEQVR4nO2bf3CT9R3HX0meFFKf/GhJ0vYJTWsroS0ozlasTByOemd1wimedip4g5Mbm6Kek/mDTXT+mnqHm+46uJ2T43Yyt57zvOGc6KkwflaQiqUNbaFNSZsmTdsk1/RHnmR/lD7QUoWkKSD2/Vee7/eTz/P9vu7z/Xw/zzdPVMXFxTGSrPnz52OxWEa0eb1etm/fnuxbEQgEk+5TPV4HOp0Og8GgXIuiiE6nAyASiRCJRBQ7URQVO4PBoNhdaBLG9WVBoLi4mGnTpuFyuaipqcFoNJKSkkJfXx8HDhxgYGCAuXPnkpKSgtFopK+vjyuuuILs7Gz8fj/V1dWEw+FkzScpShiKIAiUlpZitVoByM3NxWw24/F40Gg09Pf34/V6iUQi9Pf3o9frMZvNzJo1S4kYi8VCSUnJBQcmoeUjCALXXHMNVquVwcFBamtrCQQCiKJIfn4+Go2G3t5eZemEQiE0Gg35+fmIokg4HKa2tpZwOKyAuZCWUkKRIkkSaWlpRKNRmpubqauro6GhQVkWarWaYPBkAgwGg8iyjEqloq2tjZqaGsLhMCqVCofDgclkIiMjg2PHjiVtYuNRQlBaWlowm83k5OQgSRJtbW14vV72799Pa2srKpUKj8ej2B8+fBifz4dWq8XtdgNDidZms6FWq2ltbb1ggMA4corT6cRkMmEymXA4HHi9XgA6OjrGtB/uH9aMGTPQ6/UEAgGOHDmS6DAmRAlDCYVCuN1uRFHEbDZTWFjI4cOHlX5JksjMzASgvb1diRCAnJwcsrKykGWZ48ePEwgExjGF5CsuKOnp6RQUFGAymUhJSUGtHsrTsiwjy7JiV1xcrOQWALvdjsvl4osvvgAgGo0O3VwQKCoqoqCggIGBAbq7u6mrq8Pv9ydlcokqLijDUSEIArIsEwqFCAaDeDweWlpagKFlYbPZiEajtLe3A2C1WrHZbASDQZxOJy6XC4CsrCyMRiM6nY6pU6diNpsRRfG7BWVY4XCY6urq0/IEgF6vRxAEWltb2bt3LwBz585l+vTpmEwmxc7lcilwAMrKykhNTU1kOEnXuMv8i1EJRYpOp+Paa68lHA7T09ODz+ejpaWFSCRCd3c3kUiEzMxMSktLgaHlE4lE6OzsVHxkZ2eTkZGB0WgkNTUVrVarFHvnW3FBCYVC+Hw+JdHq9Xr0ej1ZWVkIgoDT6aSpqQmz2YwkSUiSBAwlVpfLRWNjIzAEZM6cOaSkpCj9fX19dHd3EwqF4ppAXt6lcdmfjeKC4vf72blzp3JdUFCAw+FApVKh0WiU9r179ypbcjQapa2tbUQxN7wrRSIRnE4ndXV1CU+gqelowt/9JiVcp4iiiCRJCIKAx+MZUaMAuN3uEbXJqWpubsZsNmO327HZbLjd7guqVkk40TocDoxGI729vTidTqXdarWSkZFxmr3FYlGWE8CRI0cIBoMYDAZmzJiR6DAmRAlFit1uR5IkYrEYbrcbr9eLIAgjHggbGxupqakBoLCwUFlmww+EgUCA48eP43A4kCSJzs7OC+b5JyEobrdb2T1ycnIYGBhg+vTpI07g9Hr9iM/DOcdms5Gens7Ro0fJzc1Fo9Hg9/tH5JzzrYSWTyQSYc+ePXR0dKDVaikqKsJgMBAKhWhsbESWZVJTUxGEIeaiKCLLMg0NDQQCAXQ6HUVFReh0OjweD7t27fruHzLBEJjdu3fT0dGBLMscO3aMTz75BJ/PhyzLaLVaLBYL06ZNY8qUKciyTGdnJ59++ikNDQ0MDg7i8XjYs2fPxNUnV/6MF37/ANfHWSirxnuar9Pp0Gq1yu4hiiLz5s1DFEVlsoIgEAqF2Llzp1KH6HQ6BgcHxw3k20/zU7n+wRdYemkDm9e+wee9Z+Fw/prxl/nhcHjEdhoKhZSlIAiCsoTC4fCIwiwcDp+DCraXz19/ks1HL6Pi2ZVnHTHjjpTzrbP73SeV63++jorLGtjy243fHjHJiJTvhnr5/M/r2NIwFDGlZ7D+nkA5ReqUM5ucg2FcABpaPksL2tiy9g12n8H6ewDlJJDNT64/qx3oIocSPxC42KEU38utjviAsP3l78uWHJ8u7khJUJNQxtAklDE0CWUMCa7FRed7DADc/tfs8z0ERZORMoYmoYyhSShjKOlQ7OmWMxslUdkL53D1QunMhnFoXK+MnqasRayvuJG+zx7knv1J9TxSl5ey/LkFzHboEE68FrNUA5Hmr3nvsXf47KvxuU8elKxFVFXcCNWvTigQ88oVPLbaQts/trF+cTXKyxw5eZQ9fjtL3nmc2es38KeNXQnfIznL5xQgS7Y3J8XlmFp4G7/8RRr1T2zgtWdOAQLQ3MS2Va+y8f0+Zq6+k0U53+TkOh7+8nkqm56nsuk3PLz8dIv4oTiWUXnTnFMays8NENJY8siVCDve5833u5j99J1ULDzZa155J8tXpnFozSY+Oybxw6dLxvRy70fl2L/+gFV5T7Hqn0Fmrl5B2Sib+KH4vFgLV7FNAeOmpU+L3ToDe9zO4lEpM/O7qH+lHkhDZ5CY9/IKyi8H8z1389DqPAxTdEAXVR+70c0q4urTfNxGfr6X/ffsGLpcU009ErNHRUv8UPwfsGTTe/QoYA7yyN83UW29g6olZRMHZrmEuT9IezNAF/sefY2NH+spf+tXPLY2n84/buC110+85bC+g05LOjNP85GOMRCkXWnYgc87FWPBSLPEcspoMP5drKqsZIf1Dv59V/nEgJFPbzr0oZue1DQM/W4OfZh4Yh2txBOt/wOWbNnH1B/8lBcBOMgjlZXsMJWx7qpkDe8UbXLjm6IncziBLryNp/+QR2DTO1Tts3Dz28soG+5bno7R66c+wVslDiW9nKqKK+nZ9zZPKI0HWbXhUZZPyJa8m6bGNC5fWwLYqVg9G7a+yysvHWTb/RvY2iBx49oSII1Ft0gM1tSyb7SLN/30GPRkKg3XYbb00TPqRarEoKSXU3XfzUz96i/csu1gQi7iVxdb3mqEBeU8vDLIlsW/45k19UrftmUv8ev7q5n9+N0syHfz0XPVY/h4l8ZGC1f97bqhy5dLmImbQ2+OtNJccsOcdXGNLb2cqvsWYzy8kZv+mzwghV8az2xUe5D2SwpZ8MANlOZGaa9vobPnRF9OHmUvreDuW1XUPLWFqr19Y7qo2Wyk9NUfUfHQQn5S1Mv/Civ51ygblfXZpfEdXDuWUZl3kFX/SW6ExHOeYr61nLtWlzA7V2Cw/0SjJkLYWc/WteMv8+OHMkFK7JApjZk320ntauHAruTtPsl9IDzn6qJ+a/JgDGvyPGUMTUIZQ5NQxpDqxwvLYrFYDLVajVqtVv7MNPxZo9Eof1o6tQ0gFouhUqmAk39sGt2uUqmIRqPK9Umjk33DdiqVilgshkajIRaLEY3KSvuwj1gsxvB4o9Eos2Yl/9eI/wNYyvCixAn67AAAAABJRU5ErkJggg==" width="69" height="59" class="img_Gx30"></p>
<p>In our case, we’ll create a new SSH connection by clicking on the icon in the
Status bar, and select “Connect Current Window to Host…” in the popup that
appears:</p>
<p><img decoding="async" loading="lazy" alt="Remote connection selection" src="https://developers.front-commerce.com/assets/images/remote-connection-select-05c105c117a96a7f53bf55d41d002b81.png" width="633" height="261" class="img_Gx30"></p>
<p>Then, select “Add New SSH Host…”, and type in the ssh command you’d normally use
to connect to your host machine; typically <code>ssh &lt;my_user&gt;@&lt;my_host&gt;</code>. You might
be asked to enter your host user’s password, and then VS Code will install all
the necessary packages on your host machine (you will notice a notification
stating “Setting up SSH Host on …”).</p>
<p>And that’s it! Hopefully once that is done, you'll already be set to develop on
your host from your local machine. You’ll notice the icon in your Status bar is
now showing the host you’re connected to, and you’ll be able to see the new
connection in the Remote Explorer.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="password-less-connection-with-vs-code-remote-development">Password-less connection with VS Code Remote Development<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#password-less-connection-with-vs-code-remote-development" class="hash-link" aria-label="Direct link to Password-less connection with VS Code Remote Development" title="Direct link to Password-less connection with VS Code Remote Development" translate="no">​</a></h3>
<p>One thing that might get tiring using VS Code Remote, is that you might need to
type your password each time you open a new VS Code window or each time your it
gets disconnected from your host, if your internet or local network connection
has hiccups for example. To solve this issue, I configured the SSH connection so
that is uses a RSA key I created for this purpose. Here’s how it is done:</p>
<h4 class="anchor anchorTargetStickyNavbar_A4R_" id="create-a-new-key">Create a new key<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#create-a-new-key" class="hash-link" aria-label="Direct link to Create a new key" title="Direct link to Create a new key" translate="no">​</a></h4>
<p>You can use <code>ssh-keygen</code> to create one. it is available on most Linux
subsystems, and on Windows Powershell.</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token plain">ssh-keygen </span><span class="token parameter variable" style="color:#36acaa">-q</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-b</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">2048</span><span class="token plain">  </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"./&lt;myhost&gt;_rsa"</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-t</span><span class="token plain"> rsa</span><br></div></code></pre></div></div>
<p>This will create two files: <code>&lt;myhost&gt;_rsa</code> (the private key) and
<code>&lt;myhost&gt;_rsa.pub</code> (the public key). The private key will stay on your client
(typically in the <code>~/.ssh/</code> folder on Linux subsystems)</p>
<p>The public key will need to be copied onto your host. On Linux systems you will
need to add the content of the public key to the end of the
<code>~/.ssh/authorized_keys</code> file. If the file doesn’t exist, copy your public key
in <code>~/.ssh/</code>, rename the file to <code>authorized_keys</code> and give it a permission of
600:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">chmod</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token plain"> ~/.ssh/authorized_keys</span><br></div></code></pre></div></div>
<h4 class="anchor anchorTargetStickyNavbar_A4R_" id="make-vs-code-use-the-key">Make VS Code use the key<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#make-vs-code-use-the-key" class="hash-link" aria-label="Direct link to Make VS Code use the key" title="Direct link to Make VS Code use the key" translate="no">​</a></h4>
<p>On your client IDE, go to the Remote Explorer, and click the cog icon next to
the SSH section, and then open the config file shown in the popup by clicking on
it:</p>
<p><img decoding="async" loading="lazy" alt="SSH setting icon" src="https://developers.front-commerce.com/assets/images/ssh-setting-icon-c9e179a5ce00fe276135e8341da722a4.png" width="759" height="504" class="img_Gx30"></p>
<p>In this file, you’ll find the connection you set up and its configuration. In
order to make VSCode use the key you created, add these lines to the
configuration section:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token plain">Host </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">my_host</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  HostName </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">my_host</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  User </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">my_user</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  Port </span><span class="token number" style="color:#36acaa">22</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  PreferredAuthentications publickey</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  IdentityFile </span><span class="token string" style="color:#e3116c">"~/.ssh/&lt;my_host&gt;_rsa"</span><br></div></code></pre></div></div>
<p>After this, VS Code should not ask for your user's password again!</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="pros-and-cons">Pros and cons<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#pros-and-cons" class="hash-link" aria-label="Direct link to Pros and cons" title="Direct link to Pros and cons" translate="no">​</a></h2>
<p>Every method has its own advantages and disadvantages, and using this one
certainly does not make any exception to this rule.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="pros">Pros<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#pros" class="hash-link" aria-label="Direct link to Pros" title="Direct link to Pros" translate="no">​</a></h3>
<h4 class="anchor anchorTargetStickyNavbar_A4R_" id="ease-of-use">Ease of use<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#ease-of-use" class="hash-link" aria-label="Direct link to Ease of use" title="Direct link to Ease of use" translate="no">​</a></h4>
<p>As stated in during the installation part, one of the most convenient points of
this method is the ease of use. Installation is really easy and well documented
on VS Code docs, and within VS Code itself. Configuring it on a brand new
machine should not take more than a few minutes, and you will immediately have
access to all of your host’s installed extension without needing to authenticate
to your Microsoft of Visual Studio account.</p>
<h4 class="anchor anchorTargetStickyNavbar_A4R_" id="connectivity">Connectivity<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#connectivity" class="hash-link" aria-label="Direct link to Connectivity" title="Direct link to Connectivity" translate="no">​</a></h4>
<p>Similarly, any terminal opened on the client will actually be an ssh connection
on your host, and VS Code is (most of the time) able to analyze your local app’s
log to automatically forward the right port on your local machine, which means
you will be able still connect to <code>localhost:XXXX</code> on your local machine during
development, without any server running locally. If VS Code does not detect the
local port correctly, you will only have to add it quickly through the Command
Palette <code>"Forward a Port"</code> command.</p>
<h4 class="anchor anchorTargetStickyNavbar_A4R_" id="portability">Portability<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#portability" class="hash-link" aria-label="Direct link to Portability" title="Direct link to Portability" translate="no">​</a></h4>
<p>On the hardware side, my host (laptop, in my case) still stays as portable as
ever, as I would only have to put in in my bag and I’ll still be able to develop
on-the-go the same way I do on my desktop, without having to unplug anything
(beside the laptop’s charger). And once I’m back, I can reuse my home setup.</p>
<h4 class="anchor anchorTargetStickyNavbar_A4R_" id="development-and-tests">Development and tests<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#development-and-tests" class="hash-link" aria-label="Direct link to Development and tests" title="Direct link to Development and tests" translate="no">​</a></h4>
<p>Finally, having such a setup with two machines is also an advantage for
development. Two machines means potentially two OSs, and it can become handy to
test some code on two completely different, yet very “real” environments. In my
case, My desktop runs on Windows and my laptop on Ubuntu, meaning I can easily
test OS-specific features if the need arises (it used to be really useful for
Internet Explorer, luckily gone are those days! 😅), while keeping the Linux CLI
environment I prefer.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="cons">Cons<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#cons" class="hash-link" aria-label="Direct link to Cons" title="Direct link to Cons" translate="no">​</a></h3>
<p>Here’s a catch though: two machines, also means two <em>running</em> machines, which in
turn means more energy consumption as well. This is definitely not an
environment friendly method!</p>
<p>During specific use cases, I sometimes encounter issues with port forwarding
that force me to get back to my laptop’s keyboard, for example when using
<a href="https://www.docker.com/" target="_blank" rel="noopener noreferrer" class="">Docker</a> with <a href="https://traefik.io/traefik/" target="_blank" rel="noopener noreferrer" class="">Traefik</a>,
VS Code is sometimes confused about what port to forward and where to forward it
to.</p>
<p>On the hardware side, this method renders your laptop (or host) a bit less
useful, as most of the time you’ll work at home you won’t touch it much, besides
turning it on or off. We will see in the next part other methods I tried that
actually uses both machines actively.</p>
<p>On the management side, depending on how you manage your local machine, and how
(if) you use it outside of work, you’ll have to take extra care of not mixing
work and personal things, which can be extra tricky for some, especially if
you’re pretty new to working at home.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="comparison-with-other-methods-i-have-tried">Comparison with other methods I have tried<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#comparison-with-other-methods-i-have-tried" class="hash-link" aria-label="Direct link to Comparison with other methods I have tried" title="Direct link to Comparison with other methods I have tried" translate="no">​</a></h2>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="why-not-use-a-dock-">Why not use a dock ?<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#why-not-use-a-dock-" class="hash-link" aria-label="Direct link to Why not use a dock ?" title="Direct link to Why not use a dock ?" translate="no">​</a></h3>
<p>Most docks are really great at what they are meant to do. Unfortunately, this
doesn’t include sharing peripherals between devices, which was my goal here. I
still use my dock, however in my current setup, because I use the same keyboard
/ mouse for both my machines, it would mean plugging / unplugging those everyday
which is kind of painful.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="using-both-machine-efficiently-synergy--barrier">Using both machine efficiently: Synergy / Barrier<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#using-both-machine-efficiently-synergy--barrier" class="hash-link" aria-label="Direct link to Using both machine efficiently: Synergy / Barrier" title="Direct link to Using both machine efficiently: Synergy / Barrier" translate="no">​</a></h3>
<p>This was by far my most preferred method. <a href="https://symless.com/synergy" target="_blank" rel="noopener noreferrer" class="">Synergy</a>
(and its open source clone <a href="https://github.com/debauchee/barrier" target="_blank" rel="noopener noreferrer" class="">Barrier</a>) is a
keyboard and mouse sharing software, that enable a single pair of peripherals to
work on many different machines at the same time. Unlike VS Code remote (or SSH)
only, using Synergy you are able to actually use every device’s UI as well, and
coupled to VS Code Remote, you can basically use “any” number of machines the
same way you’ll be using one.</p>
<p>Unfortunately, I had a bug on Ubuntu using Barrier that made me stop using this
method some times ago as I couldn’t find a solution. If this issue was to be
fixed however, I would hop in the Barrier train any day!</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="another-point-of-view-the-virtual-machine-way-and-tmux">Another point of view: the Virtual Machine way, and Tmux<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#another-point-of-view-the-virtual-machine-way-and-tmux" class="hash-link" aria-label="Direct link to Another point of view: the Virtual Machine way, and Tmux" title="Direct link to Another point of view: the Virtual Machine way, and Tmux" translate="no">​</a></h3>
<p>That’s a solution that requires a bit more setup, and isn’t really compatible
with VS Code either, but might be interesting for Vi / Vim and terminal power
users out there. Tmux is a terminal multiplexer, a software capable of running
multiple terminal session in a single windows. This also allows terminal session
to be “saved” and accessed from another device, meaning using terminal based
editors, your could pickup your work right where you left it seamlessly, from
pretty much any terminal on OSs supporting tmux (even from your phone!).
Coupling Tmux with a Virtual-machine hosted source code, it would be one of the
best method I can think of in terms of accessibility and portability (given you
always have an internet connection where you go, which is not a hard requirement
to satisfy in 2023).</p>
<p>However, because I’m not yet accustomed to terminal based IDEs, I only used this
method for very small tasks and personal projects.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="conclusion">Conclusion<a href="https://developers.front-commerce.com/blog/vscode-remote-development-setup-and-usage#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>My current setup is not definitive, nor perfect. I keep updating and tweaking it
as time goes on. For example, another solution I might look up in the future is
<a href="https://symless.com/guides/share-keyboard-mouse#usb-kvm-switches" target="_blank" rel="noopener noreferrer" class="">KVMs</a>, a
physical interface that connect peripherals to devices, the same way as Synergy
does on the software side. Those have been out for a while, but compatibility
was not great for a long time.</p>
<p>I think every developer should invest a bit of their time to think about their
setup from time to time. A lot of time is spend at our desks, and we now have
all kind of tools, whether they be software or hardware, to make our lives
better, so let’s take advantage of them!</p>
<p>I hope you enjoyed this quick tour of my own setup, and if you want to learn
more about other topics related to development, please tune in for more blog
posts!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Reduce friction by rediscovering your keyboard]]></title>
            <link>https://developers.front-commerce.com/blog/reduce-friction-by-rediscovering-your-keyboard</link>
            <guid>https://developers.front-commerce.com/blog/reduce-friction-by-rediscovering-your-keyboard</guid>
            <pubDate>Thu, 23 Mar 2023 18:20:00 GMT</pubDate>
            <description><![CDATA[Hey there! In this post, we'll talk about some awesome benefits that you can]]></description>
            <content:encoded><![CDATA[<p>Hey there! In this post, we'll talk about some awesome benefits that you can
enjoy when you start using keyboard shortcuts and the terminal.</p>
<p>It can really help you navigate in an application or switch between different
applications and contexts without any friction. We'll also illustrate the Unix
philosophy, and provide tips for gradually adopting these practices.</p>
<p>I hope you find this helpful!</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="why-using-your-keyboard-more">Why using your keyboard more?<a href="https://developers.front-commerce.com/blog/reduce-friction-by-rediscovering-your-keyboard#why-using-your-keyboard-more" class="hash-link" aria-label="Direct link to Why using your keyboard more?" title="Direct link to Why using your keyboard more?" translate="no">​</a></h2>
<p>As developers, we spend a lot of time typing on our keyboard. For typing code of
course, but also for searching, documentation (issue tracker, wiki…) and
communicating with others (Slack, Teams, Discord, emails…).</p>
<p>Now, think about how you switch context between different applications.</p>
<p>You’re writing code in a text editor, but want to ask a question to a teammate
on Slack:</p>
<ul>
<li class="">do you leave your keyboard to fetch your mouse (or trackpad)?</li>
<li class="">do you use “Alt + Tab”?</li>
<li class="">do you switch to a different virtual desktop? (using the keyboard)?</li>
</ul>
<p>When on Slack:</p>
<ul>
<li class="">do you use your mouse to select the person or channel you want to write to?</li>
<li class="">do you use “Ctrl + K” (or “Cmd + K) to navigate there?</li>
</ul>
<p>Try both approaches: with your mouse, and with your keyboard. How long does it
take between the last character you typed in the editor and the first one you
typed in Slack’s message input?</p>
<p>In this example, you might find that navigating to this new context without
removing your fingers from the keyboard leads to a smoother experience. <strong>It
removes friction.</strong></p>
<p>When your brain thinks about asking on Slack, within a few keystrokes you’re
ready to type your message, and a few keystrokes later you’re back in your text
editor, ready to type the next line of code. Context switching has been reduced
to its minimum, helping you to focus on the task at hand.</p>
<p>This is just an example of context switching, but be aware of it and you’ll see
that it happens all day long:</p>
<ul>
<li class="">going back and forth between our code editor and our browser</li>
<li class="">searching for information on the internet</li>
<li class="">navigating in our emails or issue tracker</li>
<li class="">committing our code changes and pushing them to the repository to open a Pull
Request</li>
<li class="">searching content in a file or a tree of files</li>
<li class="">switching to a different project, or directory</li>
<li class="">etc…</li>
</ul>
<p><strong>By rediscovering the keyboard shortcuts for each application you use, you can
significantly reduce the time it takes to switch between contexts.</strong></p>
<p>Most applications have a variety of keyboard shortcuts that allow you to
navigate and perform actions quickly and efficiently. By taking the time to
learn these shortcuts and incorporating them into your workflow, you can
streamline your work and reduce friction throughout your day.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="why-using-your-terminal-more">Why using your terminal more?<a href="https://developers.front-commerce.com/blog/reduce-friction-by-rediscovering-your-keyboard#why-using-your-terminal-more" class="hash-link" aria-label="Direct link to Why using your terminal more?" title="Direct link to Why using your terminal more?" translate="no">​</a></h2>
<p>I find it important to learn shortcuts for the applications you’re using the
major part of your day.</p>
<p>For developers, these applications would be something like: a text editor, a
browser, an instant messaging app and of course (don’t underestimate it) your
operating system!</p>
<p><strong>During your career, you’ll change the applications you use.</strong> Your team could
switch from Slack to Teams, you’ll move away from WebStorm to VSCode, you change
job and the new company uses Linear instead of Jira, Outlook instead of Gmail…</p>
<p>Every time, it will mean that you will have to learn new shortcuts again.
<strong>These changes don’t occur very often, so it is acceptable.</strong> After all, you
spend most of your day using these applications so the investment on learning
how to use them efficiently is worth it.</p>
<p>There are however a lot of tasks (you may not yet realize it) you can perform
outside those applications.</p>
<p>What if I told you that you can invest time in learning how to reduce friction:</p>
<ul>
<li class="">for your most common tasks</li>
<li class="">in a way that is gradually adoptable in your current workflow</li>
<li class="">with the ability to improve continuously without ever restarting from scratch</li>
<li class="">… for the rest of your career (and your life)</li>
</ul>
<p><strong>This is exactly what your terminal allows.</strong></p>
<p>You’ll be able to achieve a wide range of tasks thanks to the ecosystem of tools
embracing a simple yet powerful philosophy: <strong>the Unix philosophy!</strong></p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="the-unix-philosophy">The Unix philosophy<a href="https://developers.front-commerce.com/blog/reduce-friction-by-rediscovering-your-keyboard#the-unix-philosophy" class="hash-link" aria-label="Direct link to The Unix philosophy" title="Direct link to The Unix philosophy" translate="no">​</a></h2>
<blockquote>
<p>Write programs that do one thing and do it well. Write programs to work
together. Write programs to handle text streams, because that is a universal
interface.</p>
</blockquote>
<p>The <a href="https://en.wikipedia.org/wiki/Unix_philosophy" target="_blank" rel="noopener noreferrer" class="">Unix philosophy</a> is a set of
guidelines that emphasizes simplicity, modularity, and the use of small,
specialized tools that can be combined to perform complex tasks. It encourages
the use of plain text for data storage and communication, and favors the use of
pipes and filters to process data.</p>
<p>It offers a number of benefits:</p>
<ul>
<li class=""><strong>flexibility</strong>: text streams can be manipulated in many different ways. It
removes the barrier of what you can do. You’ll be able to combine small simple
programs together, in order to achieve exactly what you want to do, and make
it more complex if needed. A “pipeline” of commands is also more resilient to
changes: if data, source or process change you can adapt by changing only one
“step”</li>
<li class=""><strong>improved efficiency</strong>: automate things or find information by typing a
command in your terminal is often faster than navigating in an application and
going through several screens and forms</li>
<li class=""><strong>greater control over your data</strong>: manipulating text allows you to interact
with lots of systems and APIs, you’re not locked-in a specific vendor and can
create bridges between most of your tools… as soon as you can get data in a
textual format (i.e: output a list of files, get data from an API call, output
Git history as text…)</li>
<li class=""><strong>portability</strong>: these tools are widely available on different systems. Your
skills and knowledge are valid in different contexts: you can use them on
servers, on your current laptop… and the next ones.</li>
</ul>
<p>By focusing on small, specialized tools that can be combined in different ways,
you can tailor your daily environment to your specific needs and preferences.</p>
<p>Over time, you’ll bring new tools or change some of them without having to learn
everything again.</p>
<p>You’ll improve your environment and adapt practices <strong>incrementally and
continuously</strong>, as you make complex tasks easier to perform or automate
repetitive processes. Weeks after weeks, you’ll work more efficiently.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="ok-im-sold-whats-next">OK, I’m sold! What’s next?<a href="https://developers.front-commerce.com/blog/reduce-friction-by-rediscovering-your-keyboard#ok-im-sold-whats-next" class="hash-link" aria-label="Direct link to OK, I’m sold! What’s next?" title="Direct link to OK, I’m sold! What’s next?" translate="no">​</a></h2>
<p>Great! I’m glad that you want to reduce friction in your daily activities. <strong>I
suggest that you start now, with baby steps.</strong></p>
<p>Be aware of your hand position at every time, and learn to detect when your
fingers are about to leave your keyboard. <strong>That’s the trigger!</strong></p>
<p>Whenever this trigger occurs, stop and start asking yourself:</p>
<ul>
<li class="">
<p>what was I about to do?</p>
</li>
<li class="">
<p>is it possible to achieve this without leaving the keyboard?</p>
<ul>
<li class="">search in your application “Keyboard shortcuts” help page</li>
<li class="">search on internet</li>
<li class="">… or ask ChatGPT! Here is a prompt you can use as a base:</li>
</ul>
<blockquote>
<p><strong>I want you to act like a Unix user, and explain each tool individually.</strong></p>
<p><strong>Q:</strong> how would you get the content from a JSON URL
(<a href="https://dummyjson.com/users" target="_blank" rel="noopener noreferrer" class="">https://dummyjson.com/users</a>) and filter the
first five "names" starting with a "S", sorting them alphabetically and
outputting them as uppercased text in a file in the <code>/tmp</code> directory.</p>
<p><strong>A: let's think step by step</strong></p>
</blockquote>
<p>After a few trial/errors you could end up with this one-liner:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> https://dummyjson.com/users </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> jq </span><span class="token parameter variable" style="color:#36acaa">-r</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'.users[] | select(.lastName | startswith("S")) | .lastName'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sort</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">tr</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'[:lower:]'</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">'[:upper:]'</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> /tmp/names.txt</span><br></div></code></pre></div></div>
</li>
<li class="">
<p>try to do it with a shortcut or a command, and note it down to try to remember
it next time. You can also use <a href="https://quickref.me/" target="_blank" rel="noopener noreferrer" class="">cheat sheets</a> (I
personally started with physically printed cheat sheets on my desk!).</p>
</li>
</ul>
<p>You’ll be surprised to see how many shortcuts exist in the tools you already
use, and you will start discovering terminal commands or new programs</p>
<p>This article is already long enough. In a future article I’ll go through some of
the shortcuts and commands I use on a daily (hourly?) basis.</p>
<p>Follow this space!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Set up a WSL development environment]]></title>
            <link>https://developers.front-commerce.com/blog/wsl-development-environment</link>
            <guid>https://developers.front-commerce.com/blog/wsl-development-environment</guid>
            <pubDate>Thu, 09 Mar 2023 12:00:00 GMT</pubDate>
            <description><![CDATA[Looking to take your Windows development environment to the next level? Look no]]></description>
            <content:encoded><![CDATA[<p>Looking to take your Windows development environment to the next level? Look no
further than Windows Subsystem for Linux (WSL)! With this powerful tool, you can
quickly and easily set up a Linux-based development environment on your Windows
machine. This guide has everything you need to get started, from installing WSL
to updating packages and setting up Windows Terminal. Plus, we'll show you how
to install Node.js and Git, and give you tips for using Visual Studio Code, Zsh,
and Oh My Zsh.</p>
<p>You have two options for installation: you can either follow the
<a href="https://docs.microsoft.com/en-gb/windows/wsl/install" target="_blank" rel="noopener noreferrer" class="">full installation guide</a>,
or you can refer to the
<a href="https://docs.microsoft.com/en-gb/windows/wsl/setup/environment" target="_blank" rel="noopener noreferrer" class="">best practices for setup</a>,
which includes a step-by-step setup guide and explains important concepts such
as
<a href="https://docs.microsoft.com/en-gb/windows/wsl/setup/environment#file-storage" target="_blank" rel="noopener noreferrer" class="">File Storage</a>.</p>
<div class="theme-admonition theme-admonition-info admonition_epGf alert alert--info"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 14 16"><path fill-rule="evenodd" d="M7 2.3c3.14 0 5.7 2.56 5.7 5.7s-2.56 5.7-5.7 5.7A5.71 5.71 0 0 1 1.3 8c0-3.14 2.56-5.7 5.7-5.7zM7 1C3.14 1 0 4.14 0 8s3.14 7 7 7 7-3.14 7-7-3.14-7-7-7zm1 3H6v5h2V4zm0 6H6v2h2v-2z"></path></svg></span>Prerequisites</div><div class="admonitionContent_TPdy"><p>To set up WSL in Windows, virtualization should be enabled, commonly referred to
as SVM mode. Ensure that it is enabled in your BIOS, you can follow
<a href="https://support.microsoft.com/en-us/windows/enable-virtualization-on-windows-11-pcs-c5578302-6e43-4b4b-a449-8ced115f58e1" target="_blank" rel="noopener noreferrer" class="">this guide</a>
to locate it (it will differ depending on your motherboard). Once enabled,
proceed to Install WSL in Windows.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="install-wsl--docs">Install WSL (<a href="https://docs.microsoft.com/en-gb/windows/wsl/setup/environment#get-started" target="_blank" rel="noopener noreferrer" class="">📑 docs</a>)<a href="https://developers.front-commerce.com/blog/wsl-development-environment#install-wsl--docs" class="hash-link" aria-label="Direct link to install-wsl--docs" title="Direct link to install-wsl--docs" translate="no">​</a></h2>
<p>ℹ️ <em>If you have already followed the
<a href="https://docs.microsoft.com/en-gb/windows/wsl/install" target="_blank" rel="noopener noreferrer" class="">full install guide</a>, you
can skip this step.</em></p>
<p>To install Ubuntu, open PowerShell or Windows Command Prompt in
<strong>administrator</strong> mode by right-clicking and selecting "Run as administrator",
then enter the <code>wsl --install</code> command.</p>
<p>After running the WSL install command and restarting, Ubuntu will be installed
by default. You may change the distribution name by passing in a new name with
the <code>-d</code> flag: <code>wsl --install -d &lt;Distribution Name&gt;</code>.</p>
<p>However, I suggest staying with Ubuntu. 🙂</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="update-and-upgrade-packages--docs">Update and upgrade packages (<a href="https://docs.microsoft.com/en-gb/windows/wsl/setup/environment#update-and-upgrade-packages" target="_blank" rel="noopener noreferrer" class="">📑 docs</a>)<a href="https://developers.front-commerce.com/blog/wsl-development-environment#update-and-upgrade-packages--docs" class="hash-link" aria-label="Direct link to update-and-upgrade-packages--docs" title="Direct link to update-and-upgrade-packages--docs" translate="no">​</a></h2>
<p>When starting a new development project, updating your packages is always a good
idea. After setting up your Unix account, you can simply run this one-liner to
update the package manager:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt</span><span class="token plain"> update </span><span class="token operator" style="color:#393A34">&amp;&amp;</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt</span><span class="token plain"> upgrade</span><br></div></code></pre></div></div>
<div class="theme-admonition theme-admonition-caution admonition_epGf alert alert--warning"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>caution</div><div class="admonitionContent_TPdy"><p>If you receive an error message saying
<code>Temporary failure resolving ‘archive.ubuntu.com’</code>, it is usually due to an
invalid nameserver on the WSL installation. This can cause the WSL instance to
be unable to connect to the internet.</p><p>To confirm if this is the case, try to <code>ping www.google.com</code>. If it cannot be
pinged, this should confirm that the nameserver configuration is the issue. You
can update your configurations to the following:</p><div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token plain">$ </span><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> /etc/wsl.conf</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  </span><span class="token punctuation" style="color:#393A34">[</span><span class="token plain">network</span><span class="token punctuation" style="color:#393A34">]</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  generateResolvConf </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># disables auto generation of resolv config</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  generateHosts </span><span class="token operator" style="color:#393A34">=</span><span class="token plain"> </span><span class="token boolean" style="color:#36acaa">false</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># disables auto generation of hosts /etc/hosts</span><span class="token plain"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain" style="display:inline-block"></span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">$ </span><span class="token function" style="color:#d73a49">cat</span><span class="token plain"> /etc/resolv.conf</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain">  nameserver </span><span class="token number" style="color:#36acaa">1.1</span><span class="token plain">.1.1</span><br></div></code></pre></div></div><p>Finally, as a last step, you can protect the <code>resolv.conf</code> file by forcing the
overwrite to be disabled.</p><div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> chattr </span><span class="token parameter variable" style="color:#36acaa">-f</span><span class="token plain"> +i /etc/resolv.conf</span><br></div></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="set-up-windows-terminal--docs">Set up Windows Terminal (<a href="https://docs.microsoft.com/en-gb/windows/wsl/setup/environment#set-up-windows-terminal" target="_blank" rel="noopener noreferrer" class="">📑 docs</a>)<a href="https://developers.front-commerce.com/blog/wsl-development-environment#set-up-windows-terminal--docs" class="hash-link" aria-label="Direct link to set-up-windows-terminal--docs" title="Direct link to set-up-windows-terminal--docs" translate="no">​</a></h2>
<p>You can install any terminal, but personally, I prefer using the Preview build
because it ships features much faster than the normal version. For example, the
GUI feature only arrived around a year later on the standard version, and I have
never found it to be really stable.</p>
<p>To install, visit the Microsoft Store Apps for either:</p>
<ul>
<li class=""><a href="https://apps.microsoft.com/store/detail/windows-terminal-preview/9N8G5RFZ9XK3?hl=en-us&amp;gl=US" target="_blank" rel="noopener noreferrer" class="">Windows Terminal Preview</a></li>
<li class=""><a href="https://apps.microsoft.com/store/detail/windows-terminal/9N0DX20HK701?hl=en-us&amp;gl=US" target="_blank" rel="noopener noreferrer" class="">Windows Terminal</a></li>
</ul>
<p>And as mentioned above, GUI is supported! That means you can
<a href="https://learn.microsoft.com/en-us/windows/wsl/tutorials/gui-apps" target="_blank" rel="noopener noreferrer" class="">run Linux GUI apps on WSL</a>
😇</p>
<p><img decoding="async" loading="lazy" alt="wsl-gui-screenshot.jpg" src="https://developers.front-commerce.com/assets/images/wsl-gui-screenshot-b4e64ac28975fb23ee805e4f734db707.jpg" width="3840" height="2160" class="img_Gx30"></p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="file-storage--docs">File storage (<a href="https://docs.microsoft.com/en-gb/windows/wsl/setup/environment#file-storage" target="_blank" rel="noopener noreferrer" class="">📑 docs</a>)<a href="https://developers.front-commerce.com/blog/wsl-development-environment#file-storage--docs" class="hash-link" aria-label="Direct link to file-storage--docs" title="Direct link to file-storage--docs" translate="no">​</a></h2>
<p>To open your WSL project in Windows File Explorer, enter: <code>explorer.exe .</code> Be
sure to add the period at the end of the command to open the current directory.</p>
<div class="theme-admonition theme-admonition-tip admonition_epGf alert alert--success"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 12 16"><path fill-rule="evenodd" d="M6.5 0C3.48 0 1 2.19 1 5c0 .92.55 2.25 1 3 1.34 2.25 1.78 2.78 2 4v1h5v-1c.22-1.22.66-1.75 2-4 .45-.75 1-2.08 1-3 0-2.81-2.48-5-5.5-5zm3.64 7.48c-.25.44-.47.8-.67 1.11-.86 1.41-1.25 2.06-1.45 3.23-.02.05-.02.11-.02.17H5c0-.06 0-.13-.02-.17-.2-1.17-.59-1.83-1.45-3.23-.2-.31-.42-.67-.67-1.11C2.44 6.78 2 5.65 2 5c0-2.2 2.02-4 4.5-4 1.22 0 2.36.42 3.22 1.19C10.55 2.94 11 3.94 11 5c0 .66-.44 1.78-.86 2.48zM4 14h5c-.23 1.14-1.3 2-2.5 2s-2.27-.86-2.5-2z"></path></svg></span>tip</div><div class="admonitionContent_TPdy"><p><a href="https://learn.microsoft.com/en-gb/windows/wsl/filesystems#file-storage-and-performance-across-file-systems" target="_blank" rel="noopener noreferrer" class="">For the fastest performance, store your project files on the same operating system</a>
as the tools you plan to use. If you are working with Linux tools in a Linux
command line (Ubuntu, OpenSUSE, etc), store your files in the WSL file system.
If you're working with Windows tools in a Windows command line (PowerShell,
Command Prompt), store your files in the Windows file system. Files can be
accessed across operating systems, but doing so may significantly slow down
performance.</p></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="install-nodejs-on-wsl--docs"><strong>Install Node.js on WSL</strong> (<a href="https://docs.microsoft.com/en-us/windows/dev-environment/javascript/nodejs-on-wsl" target="_blank" rel="noopener noreferrer" class="">📑 docs</a>)<a href="https://developers.front-commerce.com/blog/wsl-development-environment#install-nodejs-on-wsl--docs" class="hash-link" aria-label="Direct link to install-nodejs-on-wsl--docs" title="Direct link to install-nodejs-on-wsl--docs" translate="no">​</a></h2>
<p>We will be using Node Version Manager (<code>nvm</code>). Follow these steps to install it
on Ubuntu (or a similar distribution):</p>
<ol>
<li class="">Open your command line.</li>
<li class="">Install cURL using the following command: <code>sudo apt-get install curl</code>. cURL
is a tool used for downloading content from the internet in the command-line.</li>
<li class="">Go to the <a href="https://github.com/nvm-sh/nvm/releases" target="_blank" rel="noopener noreferrer" class="">nvm repository</a> and find
the latest release.</li>
<li class="">Install nvm using the following command:<!-- -->
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">curl</span><span class="token plain"> -o- </span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.3/install.sh</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain"> </span><span class="token operator" style="color:#393A34">|</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">bash</span><br></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="setting-up-your-shell-zsh--oh-my-zsh"><strong>Setting up your shell (<a href="https://www.zsh.org/" target="_blank" rel="noopener noreferrer" class="">Zsh</a> + <a href="https://ohmyz.sh/" target="_blank" rel="noopener noreferrer" class="">Oh My Zsh</a>)</strong><a href="https://developers.front-commerce.com/blog/wsl-development-environment#setting-up-your-shell-zsh--oh-my-zsh" class="hash-link" aria-label="Direct link to setting-up-your-shell-zsh--oh-my-zsh" title="Direct link to setting-up-your-shell-zsh--oh-my-zsh" translate="no">​</a></h2>
<p>This step is optional, but you may want to use Zsh and Oh My Zsh if you are
looking for a more customizable and powerful shell experience.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="installing-zsh">Installing zsh<a href="https://developers.front-commerce.com/blog/wsl-development-environment#installing-zsh" class="hash-link" aria-label="Direct link to Installing zsh" title="Direct link to Installing zsh" translate="no">​</a></h3>
<p>To install zsh, open the Ubuntu app installed from the App Store and run the
following command in the terminal:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">zsh</span><br></div></code></pre></div></div>
<p>Once it's installed, type <code>zsh</code> in the terminal. It will prompt you to choose
some configuration options. We will do this later on while installing
<code>oh-my-zsh</code>, so choose option <code>0</code> to create the config file and prevent this
message from showing again.</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="installing-oh-my-zsh">Installing oh-my-zsh<a href="https://developers.front-commerce.com/blog/wsl-development-environment#installing-oh-my-zsh" class="hash-link" aria-label="Direct link to Installing oh-my-zsh" title="Direct link to Installing oh-my-zsh" translate="no">​</a></h3>
<p>Before anything else, you need to have <code>git</code> installed on your system. You can
install it by running the following command in a terminal:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt-get</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">git</span><br></div></code></pre></div></div>
<p>After installing <code>git</code>, you can then use <code>curl</code> to install oh-my-zsh.</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sh</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-c</span><span class="token plain"> </span><span class="token string" style="color:#e3116c">"</span><span class="token string variable" style="color:#36acaa">$(</span><span class="token string variable function" style="color:#d73a49">curl</span><span class="token string variable" style="color:#36acaa"> </span><span class="token string variable parameter variable" style="color:#36acaa">-fsSL</span><span class="token string variable" style="color:#36acaa"> </span><span class="token string variable operator" style="color:#393A34">&lt;</span><span class="token string variable" style="color:#36acaa">https://raw.githubusercontent.com/robbyrussell/oh-my-zsh/master/tools/install.sh</span><span class="token string variable operator" style="color:#393A34">&gt;</span><span class="token string variable" style="color:#36acaa">)</span><span class="token string" style="color:#e3116c">"</span><br></div></code></pre></div></div>
<p>This command will clone the repository and replace the existing <code>~/.zshrc</code> file
with a template from <code>oh-my-zsh</code>.</p>
<p><img decoding="async" loading="lazy" src="https://blog.joaograssi.com/windows-subsystem-for-linux-with-oh-my-zsh-conemu/install-oh-my-zsh.png" alt="https://blog.joaograssi.com/windows-subsystem-for-linux-with-oh-my-zsh-conemu/install-oh-my-zsh.png" class="img_Gx30"></p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="installing-ohmyzsh-plugins">Installing OhMyZsh Plugins<a href="https://developers.front-commerce.com/blog/wsl-development-environment#installing-ohmyzsh-plugins" class="hash-link" aria-label="Direct link to Installing OhMyZsh Plugins" title="Direct link to Installing OhMyZsh Plugins" translate="no">​</a></h3>
<p>We can supercharge our command line by adding some oh-my-zsh plugins. First,
open the zsh config by running <code>vim ~/.zshrc</code>. Next, find the line <code>plugins=</code>
and add the desired plugins.</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token assign-left variable" style="color:#36acaa">plugins</span><span class="token operator" style="color:#393A34">=</span><span class="token punctuation" style="color:#393A34">(</span><span class="token plain">git nvm </span><span class="token function" style="color:#d73a49">history</span><span class="token plain"> zsh-autosuggestions jsontools command-not-found zsh-syntax-highlighting</span><span class="token punctuation" style="color:#393A34">)</span><br></div></code></pre></div></div>
<p>I have listed my favorite plugins here, but feel free to use your own set based
on your needs. You can find a list of plugins
<a href="https://github.com/ohmyzsh/ohmyzsh/wiki/Plugins" target="_blank" rel="noopener noreferrer" class="">here</a>. Additionally, I use 3rd
party plugins that must be pulled separately:</p>
<ul>
<li class=""><a href="https://github.com/zsh-users/zsh-autosuggestions" target="_blank" rel="noopener noreferrer" class="">https://github.com/zsh-users/zsh-autosuggestions</a>
(<a href="https://github.com/zsh-users/zsh-autosuggestions/blob/master/INSTALL.md#oh-my-zsh" target="_blank" rel="noopener noreferrer" class="">installation instructions</a>)</li>
<li class=""><a href="https://github.com/zsh-users/zsh-syntax-highlighting" target="_blank" rel="noopener noreferrer" class="">https://github.com/zsh-users/zsh-syntax-highlighting</a>
(<a href="https://github.com/zsh-users/zsh-syntax-highlighting/blob/master/INSTALL.md#oh-my-zsh" target="_blank" rel="noopener noreferrer" class="">installation instructions</a>)</li>
</ul>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="enable-nvm-autoload-in-zsh">Enable NVM autoload in zsh<a href="https://developers.front-commerce.com/blog/wsl-development-environment#enable-nvm-autoload-in-zsh" class="hash-link" aria-label="Direct link to Enable NVM autoload in zsh" title="Direct link to Enable NVM autoload in zsh" translate="no">​</a></h3>
<p>Enabling the nvm autoload plugin allows you to use the appropriate node version
based on the specifications in a <code>.nvmrc</code> file in any of your projects. This
feature is especially helpful when working on multiple projects with different
node versions, as it eliminates the need to switch between incompatible
versions. With nvm autoload, you can easily switch between projects while
ensuring you are using the correct node version.</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token plain">zstyle </span><span class="token string" style="color:#e3116c">':omz:plugins:nvm'</span><span class="token plain"> autoload </span><span class="token function" style="color:#d73a49">yes</span><br></div></code></pre></div></div>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="useful-gists-for-aliases">Useful gists for aliases<a href="https://developers.front-commerce.com/blog/wsl-development-environment#useful-gists-for-aliases" class="hash-link" aria-label="Direct link to Useful gists for aliases" title="Direct link to Useful gists for aliases" translate="no">​</a></h3>
<p>To create an <code>.aliases</code> file in your home directory, run the command
<code>touch ~/.aliases</code>. Then, ensure that it is sourced in your <code>.zshrc</code> file by
adding <code>source ~/.aliases</code> to it.</p>
<p>Next, you can add the aliases and configurations used in the terminal by
following the instructions in
<a href="https://gist.github.com/paul-vd/c1ea26e19414bfcb66e7656ed7c22444" target="_blank" rel="noopener noreferrer" class="">this link</a>.</p>
<p>You will notice that there is an alias for <code>npm</code>. This is to detect which
package manager to use by searching for the nearest lock file. An alternative to
this is <a href="https://github.com/antfu/ni" target="_blank" rel="noopener noreferrer" class="">ni</a>, which is highly recommended.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="git-credential-manager-setup--docs">Git Credential Manager setup (<a href="https://docs.microsoft.com/en-us/windows/wsl/tutorials/wsl-git#git-credential-manager-setup" target="_blank" rel="noopener noreferrer" class="">📑 docs</a>)<a href="https://developers.front-commerce.com/blog/wsl-development-environment#git-credential-manager-setup--docs" class="hash-link" aria-label="Direct link to git-credential-manager-setup--docs" title="Direct link to git-credential-manager-setup--docs" translate="no">​</a></h2>
<p>The credential manager can assist with any HTTPS authentication, utilizing the
<a href="https://support.microsoft.com/help/4026814/windows-accessing-credential-manager" target="_blank" rel="noopener noreferrer" class="">Windows Credential Manager</a>.</p>
<p>To download the latest version, visit the repository at
<a href="https://github.com/GitCredentialManager/git-credential-manager/releases" target="_blank" rel="noopener noreferrer" class="">https://github.com/GitCredentialManager/git-credential-manager/releases</a>.</p>
<p>After installation and configuration, you should also add it to your Linux
shell.</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">git</span><span class="token plain"> config </span><span class="token parameter variable" style="color:#36acaa">--global</span><span class="token plain"> credential.helper </span><span class="token string" style="color:#e3116c">"/mnt/c/Program\ Files/Git/mingw64/bin/git-credential-manager-core.exe"</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="vscode--docs">VSCode (<a href="https://docs.microsoft.com/en-gb/windows/wsl/tutorials/wsl-vscode" target="_blank" rel="noopener noreferrer" class="">📑 docs</a>)<a href="https://developers.front-commerce.com/blog/wsl-development-environment#vscode--docs" class="hash-link" aria-label="Direct link to vscode--docs" title="Direct link to vscode--docs" translate="no">​</a></h2>
<p>To get started,
<a href="https://code.visualstudio.com/download" target="_blank" rel="noopener noreferrer" class="">download and install VSCode</a>. Then, add
the remote
<a href="https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.vscode-remote-extensionpack" target="_blank" rel="noopener noreferrer" class="">development extension</a>.</p>
<p>That's it you should be ready to start developing in WSL.</p>
<div class="theme-admonition theme-admonition-caution admonition_epGf alert alert--warning"><div class="admonitionHeading_C0y1"><span class="admonitionIcon_VPKI"><svg viewBox="0 0 16 16"><path fill-rule="evenodd" d="M8.893 1.5c-.183-.31-.52-.5-.887-.5s-.703.19-.886.5L.138 13.499a.98.98 0 0 0 0 1.001c.193.31.53.501.886.501h13.964c.367 0 .704-.19.877-.5a1.03 1.03 0 0 0 .01-1.002L8.893 1.5zm.133 11.497H6.987v-2.003h2.039v2.003zm0-3.004H6.987V5.987h2.039v4.006z"></path></svg></span>caution</div><div class="admonitionContent_TPdy"><p>If your WSL container resolves the <code>code</code> path to an Ubuntu installation of
VSCode, it can cause issues when you try to open a folder using a command like
<code>code ./my-folder</code>. If Git extensions crash at startup, create an alias for the
<code>code</code> command to point to your Windows installation of VSCode. Run <code>which code</code>
to detect which VSCode installation is being used.</p><p><strong>Solution:</strong></p><p>Add an alias for the <code>code</code> command that points to your Windows installation by
including it in your <code>.aliases</code> file.</p><div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token builtin class-name">alias</span><span class="token plain"> </span><span class="token assign-left variable" style="color:#36acaa">code</span><span class="token operator" style="color:#393A34">=</span><span class="token string" style="color:#e3116c">"/mnt/c/Users/%userprofile%/AppData/Local/Programs/Microsoft\ VS\ Code/bin/code"</span><br></div></code></pre></div></div></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="microsoft-powertoys-utilities-to-customize-windows--docs">Microsoft PowerToys: Utilities to customize Windows (<a href="https://docs.microsoft.com/en-us/windows/powertoys/" target="_blank" rel="noopener noreferrer" class="">📑 docs</a>)<a href="https://developers.front-commerce.com/blog/wsl-development-environment#microsoft-powertoys-utilities-to-customize-windows--docs" class="hash-link" aria-label="Direct link to microsoft-powertoys-utilities-to-customize-windows--docs" title="Direct link to microsoft-powertoys-utilities-to-customize-windows--docs" translate="no">​</a></h2>
<p>As you're setting up your Windows development environment, you might be
interested in exploring some of the additional tools available to you. One of my
personal favorites are the Microsoft PowerToys, a set of utilities designed to
help streamline and customize your Windows experience for greater productivity.
<a href="https://docs.microsoft.com/en-us/windows/powertoys/install" target="_blank" rel="noopener noreferrer" class="">Install Microsoft PowerToys</a>
to keep tweaking Windows!</p>
<p>Here are a few PowerToys features that I find particularly useful:</p>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="fancyzones">FancyZones<a href="https://developers.front-commerce.com/blog/wsl-development-environment#fancyzones" class="hash-link" aria-label="Direct link to FancyZones" title="Direct link to FancyZones" translate="no">​</a></h3>
<p>If you want to easily manage the position of each application window on your
Windows desktop, check out
<a href="https://learn.microsoft.com/en-us/windows/powertoys/fancyzones" target="_blank" rel="noopener noreferrer" class="">FancyZones</a>.
This tool allows you to customize the size and positioning of your snapping grid
with efficient layouts that suit your needs.</p>
<video autoplay="" loop="" muted="" playsinline="" width="100%"><source src="/assets/medias/FancyZones-7e8684e3370bbade39ac6ed6a579c383.mp4" type="video/mp4"><p>Your browser does not support the video tag.</p></video>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="keyboard-manager">Keyboard Manager<a href="https://developers.front-commerce.com/blog/wsl-development-environment#keyboard-manager" class="hash-link" aria-label="Direct link to Keyboard Manager" title="Direct link to Keyboard Manager" translate="no">​</a></h3>
<p></p><p>With the PowerToys Keyboard Manager, you can redefine keys and shortcut
combinations on your keyboard. For instance, you can swap the <kbd>A</kbd> key
for the <kbd>B</kbd> key. You can also swap <kbd>Ctrl</kbd> + <kbd>C</kbd> for<!-- --> <!-- -->
<kbd>⊞ Win</kbd> + <kbd>C</kbd>. This will copy text when <kbd>⊞ Win</kbd> +
<kbd>C</kbd> is pressed. If no specific application is targeted in the
PowerToys Keyboard Manager, the changes will apply globally across Windows.</p><p></p>
<video autoplay="" loop="" muted="" playsinline="" width="100%"><source src="/assets/medias/KBM-fdd3786c18ba709e78e4c515ad096211.mp4" type="video/mp4"><p>Your browser does not support the video tag.</p></video>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="file-explorer-preview-pane">File Explorer Preview Pane<a href="https://developers.front-commerce.com/blog/wsl-development-environment#file-explorer-preview-pane" class="hash-link" aria-label="Direct link to File Explorer Preview Pane" title="Direct link to File Explorer Preview Pane" translate="no">​</a></h3>
<p>The Preview Pane is an existing feature in Windows File Explorer that lets you
see a preview of a file's contents in the view's reading pane. PowerToys
enhances this feature by adding support for multiple file extensions, including
Markdown, SVG, PDF, and G-code. It also adds support for source code files with
more than 150 file extensions.</p>
<video autoplay="" loop="" muted="" playsinline="" class="w-full"><source src="/assets/medias/PreviewPane-a8c67764c65b8749f781a13c3d6b250f.mp4" type="video/mp4"><p>Your browser does not support the video tag.</p></video>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="colorpicker">ColorPicker<a href="https://developers.front-commerce.com/blog/wsl-development-environment#colorpicker" class="hash-link" aria-label="Direct link to ColorPicker" title="Direct link to ColorPicker" translate="no">​</a></h3>
<p>This Windows color picker is a must-have tool for designers and themers. It
allows you to easily select colors from any application and customize them to
your liking. The interface is user-friendly and you can copy colors to your
clipboard in different formats, including hexadecimal, RGB, and HSL. This tool
simplifies color palette management and is lightweight. Download it today to
improve your design work!</p>
<video autoplay="" loop="" muted="" playsinline="" width="100%"><source src="/assets/medias/ColorPicker-4024455ce0708be979624441c981dbdf.mp4" type="video/mp4"><p>Your browser does not support the video tag.</p></video>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="text-extractor-utility">Text Extractor utility<a href="https://developers.front-commerce.com/blog/wsl-development-environment#text-extractor-utility" class="hash-link" aria-label="Direct link to Text Extractor utility" title="Direct link to Text Extractor utility" translate="no">​</a></h3>
<p>Text Extractor allows you to copy text from anywhere on your screen, including
inside images or videos.</p>
<p></p><p>To activate the capture feature, use the shortcut (default: <kbd>⊞ Win</kbd> +<!-- --> <!-- -->
<kbd>Shift</kbd> +<kbd>T</kbd>). This will display an overlay on your screen.
Click and hold your primary mouse button, then drag to capture the text. The
captured text will be saved to your clipboard.</p><p></p>
<video autoplay="" loop="" muted="" playsinline="" width="100%"><source src="/assets/medias/PowerOCR-5b068586295b2d45d4e21c85645c41b4.mp4" type="video/mp4"><p>Your browser does not support the video tag.</p></video>
<h3 class="anchor anchorTargetStickyNavbar_A4R_" id="run-utility">Run Utility<a href="https://developers.front-commerce.com/blog/wsl-development-environment#run-utility" class="hash-link" aria-label="Direct link to Run Utility" title="Direct link to Run Utility" translate="no">​</a></h3>
<p>PowerToys Run is a quick launcher for power users that includes additional
features without sacrificing performance. It is open source and modular,
allowing for additional plugins to be added.</p>
<p></p><p>To use PowerToys Run, simply press <kbd>Alt</kbd> + <kbd>Space</kbd> and start
typing!</p><p></p>
<video autoplay="" loop="" muted="" playsinline="" width="100%"><source src="/assets/medias/Run-1125c1828b159c31469871a402efa404.mp4" type="video/mp4"><p>Your browser does not support the video tag.</p></video>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="enable-god-mode">Enable ‘God Mode’<a href="https://developers.front-commerce.com/blog/wsl-development-environment#enable-god-mode" class="hash-link" aria-label="Direct link to Enable ‘God Mode’" title="Direct link to Enable ‘God Mode’" translate="no">​</a></h2>
<p>God Mode will give you access to all of Windows’ control panels from one folder.
To enable it right-click on the desktop and select&nbsp;<strong>New &gt; Folder</strong>. Re-name the
new folder with this bit of code:</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token plain">GodMode.</span><span class="token punctuation" style="color:#393A34">{</span><span class="token plain">ED7BA470-8E54-465E-825C-99712043E01C</span><span class="token punctuation" style="color:#393A34">}</span><br></div></code></pre></div></div>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="sharing-ssh-keys-between-windows-and-wsl-2--docs"><strong>Sharing SSH keys between Windows and WSL 2</strong> (<a href="https://devblogs.microsoft.com/commandline/sharing-ssh-keys-between-windows-and-wsl-2/" target="_blank" rel="noopener noreferrer" class="">📑 docs</a>)<a href="https://developers.front-commerce.com/blog/wsl-development-environment#sharing-ssh-keys-between-windows-and-wsl-2--docs" class="hash-link" aria-label="Direct link to sharing-ssh-keys-between-windows-and-wsl-2--docs" title="Direct link to sharing-ssh-keys-between-windows-and-wsl-2--docs" translate="no">​</a></h2>
<ol>
<li class="">
<p>If you have setup ssh in windows you can copy it to your linux</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">cp</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">-r</span><span class="token plain"> /mnt/c/Users/</span><span class="token operator" style="color:#393A34">&lt;</span><span class="token plain">username</span><span class="token operator" style="color:#393A34">&gt;</span><span class="token plain">/.ssh ~/.ssh</span><br></div></code></pre></div></div>
</li>
<li class="">
<p>Fix the permissions</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">chmod</span><span class="token plain"> </span><span class="token number" style="color:#36acaa">600</span><span class="token plain"> ~/.ssh/id_rsa</span><br></div></code></pre></div></div>
</li>
<li class="">
<p>Add keychain to linux</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token function" style="color:#d73a49">sudo</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">apt</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">install</span><span class="token plain"> keychain</span><br></div></code></pre></div></div>
</li>
<li class="">
<p>Run the keychain every time you start a shell instance, you can append this
to the top of your <code>.zshrc</code> file.</p>
<div class="language-bash codeBlockContainer_Ub7h theme-code-block" style="--prism-color:#393A34;--prism-background-color:#f6f8fa"><div class="codeBlockContent_QVGb"><pre tabindex="0" class="prism-code language-bash codeBlock_yAgH thin-scrollbar" style="color:#393A34;background-color:#f6f8fa"><code class="codeBlockLines_lhOv"><div class="token-line" style="color:#393A34"><span class="token builtin class-name">eval</span><span class="token plain"> ``keychain  </span><span class="token parameter variable" style="color:#36acaa">--quiet</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--eval</span><span class="token plain"> </span><span class="token parameter variable" style="color:#36acaa">--agents</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">ssh</span><span class="token plain"> id_ed25519</span><br></div><div class="token-line" style="color:#393A34"><span class="token plain"></span><span class="token builtin class-name">command</span><span class="token plain"> </span><span class="token function" style="color:#d73a49">clear</span><span class="token plain"> </span><span class="token comment" style="color:#999988;font-style:italic"># this is why we add it to the top so that we can still se other outputs, I have not yet found a better way of silencing the keychain export messages</span><br></div></code></pre></div></div>
</li>
</ol>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="conclusion">Conclusion<a href="https://developers.front-commerce.com/blog/wsl-development-environment#conclusion" class="hash-link" aria-label="Direct link to Conclusion" title="Direct link to Conclusion" translate="no">​</a></h2>
<p>You have just learned how to set up WSL on your Windows machine and create a
powerful and efficient development environment. By following this guide, you
have installed WSL and updated packages, set up Windows Terminal and installed
Node.js and Git. These tools will help you code faster, easier, and more
securely.</p>
<p>🥳 Congratulations on completing this guide! We hope you enjoyed it and found it
useful. If you want to learn more about other topics related to development,
stay tuned as our blog will be growing!</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Some challenges of being the editor of a software intended to be integrated]]></title>
            <link>https://developers.front-commerce.com/blog/some-challenges-of-being-the-editor-of-a-software-intended-to-be-integrated</link>
            <guid>https://developers.front-commerce.com/blog/some-challenges-of-being-the-editor-of-a-software-intended-to-be-integrated</guid>
            <pubDate>Wed, 07 Dec 2022 09:55:00 GMT</pubDate>
            <description><![CDATA[Essentially, Front-Commerce is a software meant to be integrated by developers]]></description>
            <content:encoded><![CDATA[<p>Essentially, Front-Commerce is a software meant to be integrated by developers
so that a merchant can sell products to its customers in its own online store
and even
<a href="https://www.front-commerce.com/e-commerce-replatforming-big-bang-or-progressive-migration/" target="_blank" rel="noopener noreferrer" class="">without having to completely change an existing e-commerce stack</a>.
While this is probably the simplest definition of Front-Commerce (more or less
the one I use to describe my job to my family and friends 😉), it hides some
challenges we face every day.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="three-targets-developers-merchants-and-customers">Three targets: developers, merchants and customers<a href="https://developers.front-commerce.com/blog/some-challenges-of-being-the-editor-of-a-software-intended-to-be-integrated#three-targets-developers-merchants-and-customers" class="hash-link" aria-label="Direct link to Three targets: developers, merchants and customers" title="Direct link to Three targets: developers, merchants and customers" translate="no">​</a></h2>
<p>The first challenge is not really technical. As stated in the introduction, we
try to address three main personas:</p>
<ul>
<li class="">the developers integrating our solution to create an online store for…</li>
<li class="">a merchant willing to sell something to…</li>
<li class="">a customer seeking a product.</li>
</ul>
<p>Anybody having at least a
<a href="https://financesonline.com/top-15-content-management-software-systems-business/" target="_blank" rel="noopener noreferrer" class="">small experience as a software editor</a>
knows that properly addressing one persona can already be challenging, so you
can guess what it is like with three, even if they don’t necessarily want
opposing features, more targets mean more constraints.</p>
<p>Let’s take a deliberately extreme example 😃 They all want a performant store.</p>
<p>The customer:</p>
<blockquote>
<p>I want a performant and great shopping experience even in the middle of
nowhere with a low to average 3G connection.</p>
</blockquote>
<p>The merchant:</p>
<blockquote>
<p>Can I have a great shopping experience for my customers? And also, I want to
put very high quality photos and videos online. In addition, I want my pages
to be always highly up to date with customer specific and very dynamic
content. And next Friday is Black Friday! The website needs to scale, it’s the
biggest selling event of the year.</p>
</blockquote>
<p>The developers:</p>
<blockquote>
<p>The merchant wants a performant and scalable website. Is your software doing
that out of the box or can it be done by turning on a setting?</p>
</blockquote>
<p>I guess you get the idea, each target adds a set of constraints. It’s no
surprise that pleasing everyone is difficult but it’s also a stimulating
challenge.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="extensibility">Extensibility<a href="https://developers.front-commerce.com/blog/some-challenges-of-being-the-editor-of-a-software-intended-to-be-integrated#extensibility" class="hash-link" aria-label="Direct link to Extensibility" title="Direct link to Extensibility" translate="no">​</a></h2>
<p>As a software meant to be integrated by developers, Front-Commerce needs to be
extensible so that it can serve different use cases. The most obvious reason is
that each merchant wants its own customized store implementing a dedicated
shopping experience.</p>
<p>In addition, each project needs a specific set of features and while we try to
support as many as possible out of the box, having an extensible architecture
allows the developers to fill the gaps. As far as I’m concerned, it’s always a
pleasure to see very unexpected or specific features nicely implemented even if
I would never have imagined it could exist.</p>
<p>It’s also worth mentioning that in the world of composable architectures and
<a href="https://www.front-commerce.com/what-is-headless-commerce/" target="_blank" rel="noopener noreferrer" class="">headless commerce</a>,
extensibility is a key feature.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="backwards-compatibility-and-upgradability">Backwards compatibility and <em>upgradability</em><a href="https://developers.front-commerce.com/blog/some-challenges-of-being-the-editor-of-a-software-intended-to-be-integrated#backwards-compatibility-and-upgradability" class="hash-link" aria-label="Direct link to backwards-compatibility-and-upgradability" title="Direct link to backwards-compatibility-and-upgradability" translate="no">​</a></h2>
<p>Being able to implement a project is nice but that’s only the very beginning of
the story. At some point, new features and fixes for bugs will be needed. The
challenge here is to be able to deliver those without breaking anything.</p>
<p>On a practical level, that means we try to follow
<a href="https://semver.org/" target="_blank" rel="noopener noreferrer" class="">semantic versioning</a> by regularly providing patch releases
containing only bug fixes and every six weeks, we release a minor version with
new features. Those minor versions always have
<a class="" href="https://developers.front-commerce.com/docs/2.x/appendices/migration-guides/">a migration guide</a> to make the upgrade
process as frictionless as possible. And what about a major version? In the last
couple of years, we have not released any, but I’ve heard that something is
cooking 😇</p>
<p>In the code, this has a quite deep impact. When changing code, we have to keep
in mind both existing projects using our software and new ones. We also have to
think about how APIs are being used before we can make any changes to them. This
forces us to carefully encapsulate our API’s to reduce their surface as much as
possible. This has a tendency to limit the extensibility and the versatility so
as usual when it comes to code, the key is to find the right trade-off.</p>
<h2 class="anchor anchorTargetStickyNavbar_A4R_" id="anything-else">Anything else?<a href="https://developers.front-commerce.com/blog/some-challenges-of-being-the-editor-of-a-software-intended-to-be-integrated#anything-else" class="hash-link" aria-label="Direct link to Anything else?" title="Direct link to Anything else?" translate="no">​</a></h2>
<p>Oh yeah, I could have approached the support, the documentation, the developer
experience or the dependency management to name a few. This will probably be the
subject of another post…</p>
<p>In any case, all this is a part of the context in which we build Front-Commerce
and where we try find the best solutions or trade-off. As usual when it comes to
our product, we are always seeking feedback, so don’t hesitate to contact us if
you have any remarks or comments. This can only make the product better.</p>]]></content:encoded>
        </item>
    </channel>
</rss>