<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0" xmlns:cc="http://cyber.law.harvard.edu/rss/creativeCommonsRssModule.html">
    <channel>
        <title><![CDATA[Stories by Vadorequest on Medium]]></title>
        <description><![CDATA[Stories by Vadorequest on Medium]]></description>
        <link>https://medium.com/@Vadorequest?source=rss-3e4790365c74------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/0*8L4YEWuU7SiVd0UX.jpg</url>
            <title>Stories by Vadorequest on Medium</title>
            <link>https://medium.com/@Vadorequest?source=rss-3e4790365c74------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Fri, 08 May 2026 01:26:58 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@Vadorequest/feed" rel="self" type="application/rss+xml"/>
        <webMaster><![CDATA[yourfriends@medium.com]]></webMaster>
        <atom:link href="http://medium.superfeedr.com" rel="hub"/>
        <item>
            <title><![CDATA[SendGrid is deceptive about “Opened emails” statistic]]></title>
            <link>https://medium.com/unly-org/sendgrid-is-deceptive-about-opened-emails-statistic-b30eed74bbe0?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/b30eed74bbe0</guid>
            <category><![CDATA[email-marketing]]></category>
            <category><![CDATA[sendgrid]]></category>
            <category><![CDATA[open-email]]></category>
            <category><![CDATA[deception]]></category>
            <category><![CDATA[manipulation]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Sat, 26 Nov 2022 18:08:41 GMT</pubDate>
            <atom:updated>2022-11-26T18:08:41.908Z</atom:updated>
            <content:encoded><![CDATA[<h3>After in-depth analysis of SendGrid system, I came to the following conclusions:</h3><ul><li>Their “<strong>open</strong>” event is not accurate, as it can be trigger by either a <strong>BOT</strong> or a human</li><li>They know this <em>(and have built their analytics dashboard, knowingly or unknowingly, so that it doesn’t reflect this issue)</em></li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*raAJKxs8X6HgptmT.png" /></figure><p>On the above screenshot, you can see that 46 emails are being opened within 100 seconds exactly. There were 96 recipients in total, so that’d mean about 50% opened the email right away?<br>That’s odd, isn’t?</p><h3>But let’s do more testing:</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/700/0*mcQBs04k7-BPusdp.png" /></figure><p>On this batch, we got even better numbers!<br>66 recipients, 52 of them opened the email within 40 seconds. 🎉</p><p>Our marketing team must be awesome, and our product terrific for such quick enthusiasm!<br>Well, except the “click” rate is … 1%. Odd, isn’t?</p><h3>But how does that “open” event works, by the way?</h3><p>It’s simple. SendGrid adds a “pixel” in the email, basically an image which points to a script. Whenever that script is being downloaded, it means the email has been opened. Simple!<br><em>This might not be 100% accurate, but you get the big picture.</em></p><p>👉 SendGrid doesn’t know that you’ve opened the email by actually clicking on it, <strong>they only know that it has been opened</strong>.</p><h3>And what else could open our emails? 🤔</h3><p>Well, you guessed it (probably): SPAM checkers, and any other “AI” that would read the email content (like Gmail, to know whether to store it into your “Promotion” inbox and all of that).</p><p>In conclusion, SendGrid cannot make the difference between an email opened by an actual human, or by a bot!</p><p>And that would be fine, it they weren’t trying to hide it. (or at least, make it obvious that this information is not 100% accurate!)</p><p>Companies use KPIs to run a business, and sometimes, those KPIs are “how many people are reading our newsletter?”. Well, when you make strategic decisions like that based on deceptive information, it can hurt.</p><blockquote><em>Following this analysis, I’ve contacted the “Trust &amp; safety” team at SendGrid with a few advices on how to be more transparent about this fact, and decided to write a public article about it.</em></blockquote><p>I believe companies should put transparency over growth.<br>Don’t just hide your problems, but fix it instead, or at least tell us about it.</p><p>N.B: I bet other “Email delivery providers” have the exact same issue, and are deceptive, too.</p><p><em>P.S: I hope nobody got fired “for doing a bad job” because their email campaign had a 1% clicks out of 80% reads. But, Murphy law, right?</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b30eed74bbe0" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/sendgrid-is-deceptive-about-opened-emails-statistic-b30eed74bbe0">SendGrid is deceptive about “Opened emails” statistic</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[The 5 no-code most typical mistakes and how to avoid them]]></title>
            <link>https://medium.com/unly-org/the-5-no-code-most-typical-mistakes-and-how-to-avoid-them-6bde79005127?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/6bde79005127</guid>
            <category><![CDATA[airtable]]></category>
            <category><![CDATA[no-code]]></category>
            <category><![CDATA[makers]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Sat, 09 Apr 2022 12:31:25 GMT</pubDate>
            <atom:updated>2022-04-09T12:31:25.297Z</atom:updated>
            <content:encoded><![CDATA[<p>I can’t count all the no-code tools I have played with. Nor can I count all the languages and libraries I have ever worked with.</p><p>But, here are the most typical mistakes made using no-code I noticed, from my <em>relatively small</em> point of view.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*izzdQEAiXChA6TDx" /><figcaption>Photo by <a href="https://unsplash.com/@brett_jordan?utm_source=medium&amp;utm_medium=referral">Brett Jordan</a> on <a href="https://unsplash.com?utm_source=medium&amp;utm_medium=referral">Unsplash</a></figcaption></figure><h3>1) Bad understanding of database relationships, and how it will affect the business.</h3><p>Often, makers don’t think too much about how their data co-exist with each other. They’re not aware of how much this will slow them down in the long run, early bad decision with no-code aren’t less costly than with code. Some pay the price of such mistakes years after the fact.</p><blockquote>💡 No-code creates technical debt, the same way actual code does.</blockquote><p>Some tools, like Airtable, don’t help to make the right calls. Airtable, in particular, is one of the worst database I have ever worked with. While the frontend is just awesome, the backend is just as horrific. <em>It feels like it’s been built by a team of drunk underpaid interns during a summer holidays</em>. Simple things, like relationships, allow for many-to-many relations even when you specify you want a one-to-many relation. No other database does that, and for very good reasons.</p><blockquote>💡 This is the issue I’ve seen the most, and it’s <strong>very difficult to address</strong>, because there is no “right way”. The right way depends on the business state at that time and how it might evolve. Also, it will almost always evolve differently from what you thought back then, as the business matures.</blockquote><blockquote>Having someone experienced, who understand how the relationships work with the no-code tools you use (which are very different on how they usually work with code!), will be a game-changer.</blockquote><blockquote>Bad database design decisions <em>don’t wait years to bite back</em>, a couple of weeks is enough sometimes to facepalm yourself with the “if I had known” feeling.</blockquote><h3>2) Choosing the right no-code tool, for the wrong job</h3><p>This is no different from developers choosing “build the fastest compiler” using Node instead of Rust, because they’re simply “most familiar with Node”.</p><p>Tools are only great to use when used for the purpose they were created for.</p><p>For example, using Airtable when you need millions of records is a terrible idea that will either kill your business or force you to migrate when you need to focus on scaling.</p><blockquote><em>It’s not because something is possible that it’s a good idea.</em></blockquote><blockquote>💡 When looking for no-code tools, make sure you have your “functional requirements” list prepared, with the “must-have” and “nice-to-have” carefully thought. This will tremendously help you eliminate plenty of candidates early, which will in turn save you a lot of time.</blockquote><blockquote>Having a quick talk with expert who knows the ins-and-outs of a specific no-code tool can help you validate/eliminate candidates very quickly!</blockquote><h3>3) Not spending enough time analysing no-code tools to find “THE good fit”</h3><p>Often, builders want to build, and build fast. But, as pointed out previously, whatever you build will only be as good as whatever no-code tools you picked for the job. Finding the good fit is crucial. And, because of how difficult it is to understand all the limitations of every tool out there, and taking into considerations that those limitations can change at any time, it is extremely difficult to be 100% sure the tools you picked will do the job now, in 6 months, and in 2 years. No one can know that.</p><p>In this aspect, open-source software (OSS) can be much more reliable than company-made tools. Not that it cannot die when you need to scale, but even if it does, it will always give you a way to self-host things while transitioning into a new provider. Company-made tools can die, and die hard, leaving you with no alternative than re-building everything at once using a new stack, which is extremely stressful, and often feels impossible.</p><blockquote>💡 <em>The time needed to make such an analysis must not be underestimated.</em></blockquote><blockquote>The last time I had to do that, I spent 3–4 months POCing around with various tools, analysed around 30, tried around 12 and POCed about 6 of them, to finally make a conscious decision as to why we were picking those tools.</blockquote><blockquote>Ironically enough, it was the very last tool that I found that fit our business the most, after 3 months of trying and failing. I’m glad I didn’t abandon this quest until I found what I was looking for, but <em>damn</em> that was hard on the morale.</blockquote><h3>4) Not using any convention, or poor-chosen ones</h3><p>Bad conventions are even more harmful than no conventions at all. Conventions matter in the long run and save a lot of time, while avoid human mistakes.</p><p>Airtable, for instance, has very poor built-in conventions (none at all, actually). They don’t help settings any convention at all, and their “friendly” interface doesn’t help either. People think they’re writing casual text when naming tables and columns, and they aren’t aware of all the issues this might cause. Worse, Airtable encourages this by treating columns names as labels, and doesn’t allow making a difference between the “internal name”, and the “display label”.</p><p>Sure, naming your column companyName or nameOfCompany isn’t going to be much of an issue at the beginning, until someone else (or yourself!) have a change of heart and start mixing both naming conventions. From there, you’ll have a hard time finding your columns, and you’ll be more likely to make mistakes when writing automations, and those can have terrible side effects.</p><blockquote>💡 In my small company, I am <strong>not</strong> the only one using Airtable, but all new columns go through my review. My teammates can add more columns <strong>as they want</strong>, but we usually agree on the naming of the new fields previously, during our “design” phase. When things need to be fast, they do so on their own, but ask me to review their naming.</blockquote><blockquote>This might sound silly, but if we hadn’t spent that time on this, we wouldn’t be able to have the same naming convention across our 3 airtable database and more than 2000 columns.</blockquote><blockquote>I’m not saying we’ve done it perfectly, though, but we’ve highly reduced the technical debt on this side by doing it this way!</blockquote><h3>5) Not documenting things, or failing at making it discoverable</h3><p>Documentation is hard, so hard to write, even harder to make it right, and even harder to make if discoverable and actually useful for the people who need it when they need it!</p><p>It’s not for nothing that documentation is so bad for internal products, especially those written with actual code!</p><blockquote>💡 As a consultant, I can tell you most of the internal projects, whether they’re built by “experts” or interns lack good documentation. Most of the time, that documentation doesn’t even cover the most basic of things like “what this project is for? what does it do?”.</blockquote><blockquote>Documentation for no-code is not different, and, once again, no-code tools don’t always particularly help making things right.</blockquote><p>Even when the documentation is there, well written and up-to-date, it’s no-use if the person who needs it cannot find it. It must be discoverable.</p><blockquote>💡 This might come as a surprise for many non-developers, but the best documented projects out there often are open-source projects!</blockquote><blockquote>Why? Because <strong>nobody</strong> will give a damn about a project if they don’t understand what’s it for and how to use it! That’s why OSS always have great documentation, because they rarely get famous when they don’t, no matter how good the software is!</blockquote><p>Finding the right way to document your projects, one that works for everybody, is a challenge. It takes time, it often feels useless and a waste of time, but it if not done properly, it will slow down your scaling, not on the technical side, but on the human side. You won’t be able to bring in new people efficiently if things aren’t properly documented.</p><p>Also, it gets even harder when using multiple no-code tools, like Airtable, Zapier, Integromat, N8n, and having your whole business made of pieces from there and that. It makes things really hard to understand, and having an overview is quite a challenge.</p><p>&lt;aside&gt; 💡 We document all our Airtable formulas and automations (Airtable, Zapier, Integromat) into a dedicated GitHub repository. It feels like a waste of time to keep that up-to-date constantly, but it saved us quite a few times, too.</p><p>For example, when deleting/renaming a column in Airtable, it’s the only way to easily and quickly know what automations/formulas are affected. A simple “search in project” and we get the whole overview of every affected components. This gives me such a great piece of mind for maintaining things that I can only advise you to do the same, although I wish it was simpler and automated.</p><p>There are plenty of other “typical mistakes” with no-code, but this is my curated top 5. Don’t hesitate to share your thoughts and feedbacks!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6bde79005127" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/the-5-no-code-most-typical-mistakes-and-how-to-avoid-them-6bde79005127">The 5 no-code most typical mistakes and how to avoid them</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[A 2021 guide about structuring your Next.js project in a flexible and efficient way]]></title>
            <link>https://medium.com/unly-org/a-2021-guide-about-structuring-your-next-js-project-in-a-flexible-and-efficient-way-b5459a2a946e?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/b5459a2a946e</guid>
            <category><![CDATA[project-structure]]></category>
            <category><![CDATA[folder-structure]]></category>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[react]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Thu, 21 Jan 2021 14:18:46 GMT</pubDate>
            <atom:updated>2022-04-09T14:09:25.512Z</atom:updated>
            <content:encoded><![CDATA[<p>Next.js is very unopinionated about how to structure your Next.js project.</p><blockquote><em>The only thing you must really be careful about is to not have anything under </em><em>pages that aren&#39;t actual pages (e.g: tests, components, etc.), because there is no way to ignore them and Next will bundle and deploy them as actual pages.</em></blockquote><p>You can choose to have your code at the root level (/pages) or under src (/src/pages). We prefer the latter, because it makes it more obvious what is actual app-related code and what isn&#39;t.</p><h3>The usual folder structure</h3><p>Most people will organize their project using a folder structure such as:</p><pre>/public<br>    favicon.ico<br>/src<br>    /components<br>        /elements<br>            /auth<br>                AuthForm.tsx<br>                AuthForm.test.ts<br>            /[Name]<br>                [Name].tsx<br>                [Name].test.ts<br>    /hooks<br>    /types<br>    /utils<br>    /test<br>        /api<br>            authAPI.test.js<br>            [name]API.test.js<br>        /pages<br>            index.test.js</pre><pre>    /pages<br>        /api<br>          /authAPI<br>              authAPI.js<br>          /[name]API<br>              [name]API.js<br>        _app.tsx<br>        _document.tsx<br>        index.tsx</pre><p>This design pattern is very common, and it’s great for small project because it makes it obvious where your files should be located. They’re grouped by “kind of files”. It’s very similar to the MVC design pattern many developers are familiar with.</p><p>The main issue with this design pattern is its lack of scalability.</p><p>While it’s great at the beginning, <em>and can be a good fit depending on the size of your project</em>, you’ll realize a some point you’d find your files faster if they were grouped together by “<strong>module</strong>”.</p><p>Once you reach 6–10 unrelated features, you’ll wish to have the components files close to the utilities and to the TS type that are specific to your UI components, or even maybe your data model.</p><p>Also, you might prefer having all files related to a particular 3rd party within the same folder, as a module. (e.g: Sentry, Amplitude, etc.)</p><p>At some point, splitting files based on their kind will not be good enough. <strong>That’s where you’ll need modules</strong>.</p><h3>The flexible and “modular” folder structure</h3><p>Another way to organize things is to introduce <strong>modules</strong>.<br>Modules help group together code that is related to each other. They’re not a replacement for what’s common.</p><p>Here is how we might convert our previous folder structure to something a bit more modular:</p><pre>/public<br>    favicon.ico<br>/src<br>    /common<br>        /components<br>            /elements<br>                /[Name]<br>                    [Name].tsx<br>                    [Name].test.ts<br>        /hooks<br>        /types<br>        /utils<br>    /modules<br>        /auth<br>            /api<br>                AuthAPI.js<br>                AuthAPI.test.js<br>            /components<br>                AuthForm.tsx<br>                AuthForm.test.ts<br>            auth.js<br>    /pages<br>        /api<br>          /authAPI<br>              authAPI.js<br>          /[Name]API<br>              [Name]API.js<br>        _app.tsx<br>        _document.tsx<br>        index.tsx</pre><p>We added a new src/modules/ folder where we group all files related to the same feature (here, the authentication as &quot;auth&quot;), instead of splitting the &quot;auth&quot; code everywhere, it is now centralized into a single folder.</p><p>You might have noticed the only thing that hasn’t changed is the src/pages/ directory. I&#39;ll repeat myself, but you must not have anything there that isn&#39;t either a page or an API endpoint.</p><p>Everything related to the authentication is now in /src/modules/auth, it&#39;s much easier/faster to understand the code being used to authenticate now!</p><p>But, you don’t want to always use modules, right? Sometimes you’re writing some kind of utility that doesn’t really fit in any module, something you’ll want to write some code quickly and be done with it.</p><p>Modules introduce “thoughts complexity”, because now you have a conscious choice to make about where your file should be. It was easier before to make this decision, because grouping files by kind is effortless, it’s a choice that has an actual answer to it. Moving a component to the hooks folder is wrong, while moving it to the components is correct.</p><blockquote><strong>It’s easy to know you did it right.</strong> (or wrong)</blockquote><p>But, with modules, there is no right/wrong answer! Making it harder to make decisions. Sometimes you won’t know, it won’t be obvious at first (it may never be). Sometimes you’ll figure it out afterwards (“oh, that’s actually a module”).</p><p>And because modules aren’t the universal solution to this problem, <strong>the key is to allow both</strong>.</p><p>The common directory should be used for everything that isn&#39;t a module, while the modules directory should be used by everything you feel should be a &quot;module&quot;.</p><p><strong>This way, you get the best of both worlds:</strong></p><ul><li>The ability to <strong>quickly</strong> add code <strong>without thinking</strong> much about where it should be (common).</li><li>The ability to organize <strong>at your own pace</strong> when you feel like that thing has grown too big and all those pieces of code should be brought together (converting from common to modules).</li><li>The ability to <strong>quickly find your code</strong> in your existing modules and to have an <strong>overview</strong> of how big a module is.</li></ul><p>I’m the author of <a href="https://github.com/UnlyEd/next-right-now">Next Right Now</a>, a Next.js production-ready boilerplate, and the above folder structure is what we’re using since January 20, 2021. It is the result of <a href="https://github.com/UnlyEd/next-right-now/discussions/183">feedbacks from the NRN community</a>.</p><p>Alongside this new folder structure, Next Right Now has also migrated to “<a href="https://unlyed.github.io/next-right-now/reference/module-path-aliases">Module path aliases</a>”, which uses absolute paths instead of relative paths for importing modules. (e.g: import (&#39;@/common/hooks/useStuff&#39;) instead of import (&#39;../../../common/hooks/useStuff&#39;).</p><blockquote>If you want to learn more on the topic, read the <a href="https://unlyed.github.io/next-right-now/reference/folder-structure">NRN folder structure documentation</a>!</blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b5459a2a946e" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/a-2021-guide-about-structuring-your-next-js-project-in-a-flexible-and-efficient-way-b5459a2a946e">A 2021 guide about structuring your Next.js project in a flexible and efficient way</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Migrating Next.js (+Jest/Storybook/Cypress) to use module path aliases, instead of relative paths]]></title>
            <link>https://medium.com/unly-org/migrating-next-js-jest-storybook-cypress-to-use-module-path-aliases-instead-of-relative-paths-5b7d62c5e9cb?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/5b7d62c5e9cb</guid>
            <category><![CDATA[jest]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[cypress]]></category>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[webpack]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Mon, 18 Jan 2021 13:10:33 GMT</pubDate>
            <atom:updated>2022-04-09T14:11:40.857Z</atom:updated>
            <content:encoded><![CDATA[<p>Most projects use the well-known relative paths to resolve files and modules. For instance: import &#39;../config.ts&#39;;</p><p>Sometimes, especially on big projects, it becomes this:<br>import { NRN_DEFAULT_THEME } from &#39;../../common/constants&#39;;</p><p>But, did you know you can convert to something like this:<br>import { NRN_DEFAULT_THEME } from &#39;@/common/constants&#39;;</p><p>This is a <a href="https://nextjs.org/docs/advanced-features/module-path-aliases">“module path alias”</a>, and Next.js has support for those <a href="https://nextjs.org/blog/next-9-4#absolute-imports-and-aliases">since 9.4</a> (May, 2020).</p><p>The main advantages to module path aliases are:</p><ul><li>Avoids “../” spaghetti code</li><li>Avoid breaking your imports when moving them around (sure, IDE help but when you move a lot of files around, they get confused too)</li><li>Avoid changing the file content when moving the file around, which in turn leads to avoiding Git conflicts! (this is, by far, the main advantage, IMHO)</li><li>You can copy/paste your code, and it’ll work as-it, even if you pasted it into a file on another folder level (and that’s great)</li><li>You can still use relative imports if you want, it’s not a lock-in!</li><li>Do you see more?</li></ul><p>So, why not using them? Why don’t we see that more often?</p><ul><li>It requires configuration in several tools (babel, webpack)</li><li>It affects all tools in your project, because all file loaders must be compatible, and configured properly (this is, by far, the main reason why it’s so complicated to get right)</li></ul><p>If you use a very simple Next.js project, you can simply change your tsconfig.json to something like this:</p><pre>{<br>  &quot;compilerOptions&quot;: {<br>    &quot;baseUrl&quot;: &quot;.&quot;,<br>    &quot;paths&quot;: {<br>      &quot;@/common/*&quot;: [<br>        &quot;src/common/*&quot;<br>      ],<br>      &quot;@/components/*&quot;: [<br>        &quot;src/common/components/*&quot;<br>      ],<br>      &quot;@/utils/*&quot;: [<br>        &quot;src/common/utils/*&quot;<br>      ],<br>      &quot;@/modules/*&quot;: [<br>        &quot;src/modules/*&quot;<br>      ]<br>    },</pre><blockquote><em>The above mapping is what </em><a href="https://github.com/UnlyEd/next-right-now/discussions/183"><em>we’re thinking of using in Next Right Now</em></a><em>, but you probably want something specific to your app and way of doing things!</em></blockquote><p>Using a mapping as described above will be enough for Next.js to use import { NRN_DEFAULT_THEME } from &#39;@/common/constants&#39;; properly!</p><h3>How to convert all relative paths to module paths?</h3><p>The relative-to-alias NPM module helped us a ton.</p><p>It was hard to configure properly because it wasn’t doing anything at first (due to a misconfiguration on our side), but we eventually managed to make it work.</p><p>npx relative-to-alias --src &#39;src&#39; --alias &#39;@/common&#39; --alias-path &#39;./src/common&#39; --extensions &#39;ts,tsx&#39; --language &#39;typescript&#39;</p><p>Running this replaced all relative paths to @/common/.... We eventually <a href="https://github.com/UnlyEd/next-right-now/blob/5cd7a3cc1470a0dac5ffb0f34530a5d7b3ceb69a/package.json#L84-L87">wrote a script for this</a>.</p><p>This is a quick and easy way to migrate an existing project.</p><blockquote><em>Make sure to commit all changes before running the </em><em>codemod:module-path-aliases! It&#39;ll change lots of files and should be done in a dedicated commit/PR.</em></blockquote><h3>Is that it?</h3><p>Depending on how big your project is, it might… But:</p><ul><li>If you’re using Jest (you probably are)</li><li>If you’re using Cypress</li><li>If you’re using Storybook</li></ul><p>Then, you’ll need to configure them, so they understand what @/ means!</p><p>And, unfortunately, that’s the most complicated part to figure out by yourself… Because they all use a different way of doing so. They don’t all rely on tsconfig.json, and you don&#39;t necessarily only use TypeScript, but JavaScript as well!</p><p>Here is an overview of where you’ll need to make changes:</p><ul><li><a href="https://github.com/UnlyEd/next-right-now/pull/265/files#diff-b55cdbef4907b7045f32cc5360d48d262cca5f94062e353089f189f4460039e0">tsconfig.json</a></li><li><a href="https://github.com/UnlyEd/next-right-now/pull/265/files#diff-1e058ca1442e46581b13571fb8d261f9e1f5657e26c96634d4c1072f0f0347f1">jest.config.js</a></li><li><a href="https://github.com/UnlyEd/next-right-now/pull/265/files#diff-7c73a5b98f30e40574b7149a83a19e335c5ee48b8c9c58e4e6cbfe6a07777037">cypress/tsconfig.json</a></li><li><a href="https://github.com/UnlyEd/next-right-now/pull/265/files#diff-88916def1b0ce362d14fad4ff9e7ef8a93dc5eb184c798aac06a4564a9ac4ec9">.storybook/jsconfig.json</a></li><li><a href="https://github.com/UnlyEd/next-right-now/pull/265/files#diff-962be72e9a91e7a94e8a2eb9ecb637f7e4a399fbf80b2a55c623ee477c632715">cypress/jsconfig.json</a></li><li><a href="https://github.com/UnlyEd/next-right-now/pull/265/files#diff-cafe2123a72c4ce3a9f7e9ee4b0e188256eb02d7ec1e54fa2cadfac99b22f92b">.storybook/main.js:webpackFinal</a></li><li><a href="https://github.com/UnlyEd/next-right-now/pull/265/files#diff-1e058ca1442e46581b13571fb8d261f9e1f5657e26c96634d4c1072f0f0347f1">jest.config.js:moduleNameMapper</a></li></ul><p>The jsconfig.json are necessary for WebStorm to resolve the aliases used within .js files. (Otherwise, it compiles but WebStorm displays &quot;Module not found&quot;)</p><p>Jest has a particular way to understand aliases. Storybook doesn’t have tsconfig.json and it must be configured via their Webpack override.</p><p>In conclusion, it can be quite complicated (with a lot of duplicated configuration) to make Module aliases work on a whole project. It takes some time to understand how each 3rd party needs to be configured.</p><blockquote><em>At this time, I don’t have any feedback experience regarding actual usage. This is still </em><a href="https://github.com/UnlyEd/next-right-now/pull/265"><em>under peer-review</em></a><em>, and it might take a while until we get familiar with those new paths.</em></blockquote><p>Also, it is <strong>concerning how complicated the configuration is</strong>. It’s being <strong>duplicated</strong> in no less than <strong>7 different files</strong>! And one might be concerned about what’d happen if it ever breaks.</p><p>But, in such event, I guess we can solve it with another codemod that converts all module aliases back to relative paths!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=5b7d62c5e9cb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/migrating-next-js-jest-storybook-cypress-to-use-module-path-aliases-instead-of-relative-paths-5b7d62c5e9cb">Migrating Next.js (+Jest/Storybook/Cypress) to use module path aliases, instead of relative paths</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Using Storybook 6.1 with Next.js and Emotion 11 — Advanced usage and best practices]]></title>
            <link>https://medium.com/unly-org/using-storybook-6-1-with-next-js-and-emotion-11-advanced-usage-and-best-practices-77a73db46bdb?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/77a73db46bdb</guid>
            <category><![CDATA[storybook]]></category>
            <category><![CDATA[vercel]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[github-actions]]></category>
            <category><![CDATA[nextjs]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Sun, 17 Jan 2021 14:24:07 GMT</pubDate>
            <atom:updated>2022-04-09T14:13:25.627Z</atom:updated>
            <content:encoded><![CDATA[<h3>Using Storybook 6.1 with Next.js and Emotion 11 — Advanced usage and best practices</h3><p>The <a href="https://github.com/UnlyEd/next-right-now">Next Right Now</a> boilerplate recently got an interesting upgrade!</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/0*LNkQvBMsBC1mcqvw.jpg" /><figcaption>Awesome image taken from <a href="https://dev.to/aprietof/next-js-typescript-storybook-the-really-simple-guide-2019-fei">https://dev.to/aprietof/next-js-typescript-storybook-the-really-simple-guide-2019-fei</a></figcaption></figure><h3>Overview</h3><p>We’ve added Storybook side-by-side with our Next.js application. It took us about 4 days of intensive work.</p><p>We had never used Storybook in the past, and we were looking for a Design System to help our designers and developers build components in a better way, with proper documentation, functional testing, accessibility testing, and interact with our components. Storybook helped us achieve all of that — and even a bit more.</p><blockquote><em>While this work has been done on Next Right Now, any Next.js project can benefit from it.</em></blockquote><blockquote><em>Check out the </em><a href="https://github.com/UnlyEd/next-right-now/pull/251"><em>Pull Request</em></a><em> and </em><a href="https://unlyed.github.io/next-right-now/guides/storybook/"><em>documentation</em></a><em> to learn more about it.</em></blockquote><p>Check out the result on our <a href="https://nrn-v2-mst-aptd-at-lcz-sty-storybook.vercel.app/?path=/story/next-right-now-welcome-to-nrn--page">Storybook demo</a>.</p><h3>Main features</h3><ul><li>Compatible with TypeScript</li><li>Compatible with Emotion 10/11, useful if you use Emotion yourself, or libs using Emotion</li><li>Next.js router (decorator)</li><li>Compatible with Sentry</li><li>Compatible with node-related libs</li><li>Compatible with CSS Modules</li><li>Static site automatically deployed on Vercel, using GitHub Actions</li><li>Automated tests using Cypress, to make sure you get warned if you accidenly break your static site</li><li>Support for i18next and Locize provider (fetched and cached upon build)</li></ul><h3>Methodology and learnings</h3><h3>Initial configuration</h3><p>It wasn’t easy. The most difficult part was Emotion/Node.js, because it required some Webpack/Babel tricks with solutions and workarounds splattered all over the web. Emotion was quite a pain in particular, because their TS types clash between v10 and v11. Next Right Now had been upgraded to v11 last week, but some libraries we use are still using v10, which creates a few inconsistencies, even after configuring Webpack and Babel as recommended.</p><p>Definitely not something easy to do. It took us about one and half day of work to get it right. Also, we directly integrated automated deployments (CI/CD) using Vercel and GitHub Actions. That part was easy because we have quite a lot of experience with those already.</p><h3>Build a solid Storybook foundation</h3><p>Once all the pieces had been properly configured, we started looking at the Storybook ecosystem. We wasted 2 good hours trying to use knobs before we figured it wasn&#39;t the recommended way to do things anymore. (Replaced by controls in v6)</p><p>The <a href="https://storybook.js.org/addons/">https://storybook.js.org/addons/</a> was great to get an overview of all existing addons, and we went through the whole list, to look at all those that were promising. Eventually, we selected 8 officials and 5 community-maintained. Checking all of them took us another day.</p><pre>// Officials<br>    &quot;@storybook/addon-a11y&quot;: &quot;6.1.14&quot;,<br>    &quot;@storybook/addon-actions&quot;: &quot;6.1.14&quot;,<br>    &quot;@storybook/addon-console&quot;: &quot;1.2.2&quot;,<br>    &quot;@storybook/addon-essentials&quot;: &quot;6.1.14&quot;,<br>    &quot;@storybook/addon-google-analytics&quot;: &quot;6.1.14&quot;,<br>    &quot;@storybook/addon-jest&quot;: &quot;6.1.14&quot;,<br>    &quot;@storybook/addon-links&quot;: &quot;6.1.14&quot;,<br>    &quot;@storybook/addon-storysource&quot;: &quot;6.1.14&quot;,</pre><pre>    // Community<br>    &quot;storybook-addon-designs&quot;: &quot;5.4.3&quot;,<br>    &quot;storybook-addon-next-router&quot;: &quot;2.0.3&quot;,<br>    &quot;storybook-addon-performance&quot;: &quot;0.14.0&quot;,<br>    &quot;storybook-css-modules-preset&quot;: &quot;1.0.5&quot;,<br>    &quot;storybook-mobile&quot;: &quot;0.1.29&quot;,</pre><p>We documented them all in the <a href="https://github.com/UnlyEd/next-right-now/blob/e5aba8eaf02918d9506008ee1f11c38954fedc86/.storybook/main.js#L53-L196">.storybook/main.js file</a></p><p>Those addons were “must-haves” to us. Eventually, we disabled storysource and we don&#39;t actually use performance much yet, but it looks promising.</p><blockquote><em>Storybook has a special </em><em>essentials package regrouping all the </em><a href="https://storybook.js.org/addons/essentials"><em>&quot;essential&quot; features</em></a><em>, it definitely helped us! </em>(but we&#39;re greedy and wanted more!)</blockquote><h3>Mock our app behavior</h3><p>And then, we had to mock stuff around, using Decorators, configuring i18n with Locize so our components could behave in Storybook the same way they behave in Next Right Now. Overall, it wasn’t so hard, but <a href="https://github.com/UnlyEd/next-right-now/blob/e5aba8eaf02918d9506008ee1f11c38954fedc86/.storybook/preview.js">took time to get right</a>.</p><h3>Writing actual component Stories</h3><p>Once we were done with the configuration part (around 2.5 days in total), it was time to do the actual work: <strong>Write stories for ALL our components</strong>.</p><p>And… it was hard. We had written a few stories during the configuration (of course!) and we knew the basics, but it wasn’t obvious what were the “Best practices” really. Also, looking at stuff on the web didn’t help and was quite confusing, as they were plenty of examples using v4 or v5, and not many using v6 (which is still quite new!).</p><p>At some point, we figured how we’d write our components in such a way we’d avoid code duplication (within stories). But it took us much longer than we wished to.</p><blockquote><em>To be honest, we don’t really know if our way is “the” way. It’s one that makes sense, avoids code duplication, is simple to maintain and extend.</em></blockquote><blockquote><em>Is it good? </em>Definitely<em>.<br>It is the best? </em><strong><em>You tell me</em></strong><em>.</em></blockquote><p>Eventually, we managed to write stories for all our components. It took us about 2.5 days.</p><h3>Caveats and pains</h3><ul><li>Babel/Webpack are real pains. They’re like a double edge sword, either you figure out how to configure stuff or you don’t. If you do, great, you can now work on the real stuff. If you don’t, well, <em>you suck</em>. Or that’s actually what <em>it feels like</em>. Personally, I hate configuring Babel/Webpack, because I’m not familiar with them, and I don’t want to learn them either. They’re too complicated for my taste, and they evolve with breaking changes too often, too. I don’t know why it was so complicated, it just was, and it could have been avoided.</li><li>Storybook documentation is good, but it’s not great yet. We got lost several times about how to write our components, met a few bugs that made us feel dumb (<em>hello </em><em>.storybook/manager.js with your broken cache</em>), had to go around and around the documentation to find how to configure default stories, override stories, how to disable controls for properties (we eventually wrote a withPropMock HOC for this). TS helps a ton, but there are yet quite a bit of uncovered documentation. They&#39;re <a href="https://github.com/storybookjs/storybook/issues/13499">working on it</a>, and we&#39;ve seen far worse. Overall, we had a good experience, but it can improve!</li><li>Some stuff that should be simple (like sharing CSS for all stories) was quite complicated and really not developer-friendly.</li><li>We ended up re-writing our stories completely several times, until we found the “right” way.</li></ul><h3>Final words</h3><p>Adding Storybook was exciting, a bit needlessly complicated, but <a href="https://nrn-v2-mst-aptd-at-lcz-sty-storybook.vercel.app/">the result is great</a>. It’s going to be tremendously helpful for our Product Owner, Designers and Developers to collaborate at <a href="https://github.com/UnlyEd">Unly</a>, and the team is very excited to benefit from this update once we’ll ship it into our private Next Right Now forks!</p><p>Having experienced a bit of Storybook v5 and v6, the v6 provides a much better developer experience, great job to the team, it’s lovely to see OSS building such great products!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=77a73db46bdb" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/using-storybook-6-1-with-next-js-and-emotion-11-advanced-usage-and-best-practices-77a73db46bdb">Using Storybook 6.1 with Next.js and Emotion 11 — Advanced usage and best practices</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Next Right Now in 2020 — Most flexible and production-ready boilerplate for Next.js]]></title>
            <link>https://medium.com/unly-org/next-right-now-in-2020-most-flexible-and-production-ready-boilerplate-for-next-js-c7e39bf1474?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/c7e39bf1474</guid>
            <category><![CDATA[react]]></category>
            <category><![CDATA[github-actions]]></category>
            <category><![CDATA[vercel]]></category>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[open-source]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Mon, 11 Jan 2021 10:37:48 GMT</pubDate>
            <atom:updated>2021-01-11T10:37:48.190Z</atom:updated>
            <content:encoded><![CDATA[<h3>Next Right Now in 2020 — Most flexible and production-ready boilerplate for Next.js</h3><p><a href="https://unlyed.github.io/next-right-now/">Next Right Now</a> is a production-ready boilerplate for Next.js.</p><p>Authored by <a href="http://unly.org/">Unly</a> less than a year ago, it has recently reached 500 GitHub stars, with more than 1000 unique visitors in December 2020 alone!</p><p>Our main motivation by releasing our internal framework as open-source software, was to share it with the community, hoping the quality would increase.</p><p>And it did! In 2O2O, Next Right Now was visited by people from 139 different countries, for a total of ~6k unique visitors!</p><p>Open-source takes time, it really does. But it’s part of our core at Unly, our goal is to help students access higher education, and open-source is naturally on the way!</p><h3>2020 statistics</h3><p>Unsurprisingly, most visitors were from the United States.<br>What was more surprising through, is that India is ranked 2nd!<br>And France is 3rd, that was also a great surprise considering we’re a French company ourselves!</p><p>Chrome was used by 80% of the developers reading the NRN documentation, Safari comes second (10%), then Firefox (6%) and Edge (3%). Nothing astounding here.</p><p>Bounce rate was around 50%, which isn’t bad. There were more than 35k page views in total, with an average session duration of 2:36mn.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/880/0*wSwnUTzzt-MBYBIO.png" /></figure><p>Those statistics are interesting and show us developers come back and spend even more time on the documentation, which is a great sign for conversion. That means people like what they see, and they come back for more.</p><p>And more, we’ve got!</p><h3>2020 features</h3><p>There have been some incredible features implemented in 2020, thanks to the community:</p><ul><li>Trigger a GitHub Action workflow remotely (workflow dispatch), we’ve used this to trigger Vercel deployments from our Stacker app and from GitHub Actions UI itself!</li><li>A Vercel deployment <a href="https://unlyed.github.io/next-right-now/guides/api-endpoints/">webhook</a> was added in December 2020, making it possible to get notified when a Vercel deployment is completed. We’ve used this to update our Airtable dataset automatically, works very great!</li><li>We’ve released <a href="https://github.com/UnlyEd/github-action-await-vercel">our first GitHub Action</a> less than 2 weeks ago (awaits for a Vercel deployment to be completed) and we’re already <a href="https://github.com/UnlyEd/github-action-store-variable">working on a new one</a>! (share GitHub Action variables between jobs) and <a href="https://github.com/UnlyEd/next-right-now/pull/239">it’s being beta-tested at the moment</a>!</li><li>We’ve recently updated the Next Right Now documentation, and explained in-depth all our <a href="https://unlyed.github.io/next-right-now/guides/scripts-and-utilities/#scripts">built-in scripts</a> and <a href="https://unlyed.github.io/next-right-now/guides/scripts-and-utilities/#utilities">built-in utilities</a>, among many other things.</li><li>Automated versioning, using the Git commit history.</li><li>Automated releasing, using GitHub Actions! (we’ve added quite a lot of automations this last month alone!)</li><li>Auto-aliasing of Vercel custom domains, for production but also preview! (which is a paid feature on Vercel, and quite an expensive one, too)</li></ul><h3>What about 2021?</h3><p>We have many things planned for 2021, and we’re very excited by the recent Vercel/Next.js announcements. 2021 looks promising already!</p><p>Also, we’re gonna start a new big open-source project! It might just become the most flexible Chatbot out there ;)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c7e39bf1474" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/next-right-now-in-2020-most-flexible-and-production-ready-boilerplate-for-next-js-c7e39bf1474">Next Right Now in 2020 — Most flexible and production-ready boilerplate for Next.js</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Next Right Now — Flexible production-grade boilerplate for building web apps (monorepo), with…]]></title>
            <link>https://medium.com/unly-org/next-right-now-flexible-production-grade-boilerplate-for-building-web-apps-monorepo-with-b4b92288e89b?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/b4b92288e89b</guid>
            <category><![CDATA[monorepo]]></category>
            <category><![CDATA[serverless]]></category>
            <category><![CDATA[zeit]]></category>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[nextjs]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Tue, 03 Mar 2020 15:11:19 GMT</pubDate>
            <atom:updated>2020-03-05T16:06:22.425Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/1*z4FQFYDwCbu7J9u-qsRooQ.jpeg" /></figure><h3>Next Right Now — Flexible production-grade boilerplate for building web apps (monorepo), with Next.js, Zeit and TypeScript</h3><p>Building a web app is hard. Building a production-grade app with a high Developer Experience is even harder. Configuring all must-needed frameworks and libraries is quite a challenge, and takes weeks, if not months of hard work.</p><p>Monitoring, analytics, reusable styles (css-in-js), graphql, i18n, testing, end-to-end testing, deployment pipeline (CI/CD), typescript, serverless… All these things are must-haves in 2020, and making them all work together is another challenge.</p><p>That’s why we released <a href="https://github.com/UnlyEd/next-right-now">https://github.com/UnlyEd/next-right-now</a>, a boilerplate to help get started with all that. Though opinionated, it’s flexible enough to adapt to your own needs. The goal is to get started with a production-grade setup in a couple of hours, instead of a couple of weeks (at the very least).</p><p>There are so many tools in the JS ecosystem now that one must have an opinion on what’s good-enough and what isn’t. It takes time to compare all css-in-js libraries, and that’s just one tiny choice one must do to build isomorphic/universal web applications nowadays.</p><p>Next Right Now will help you get started quickly, and can also be used as a great learning resource, because we’ve documented about everything.</p><p>You want to build your own blog? An e-commerce website? Some showcase web app? NRN can help, from development to production.</p><p>And, it’s flexible. Because you will not agree with all our opinions, and that’s fine. Just get rid of what you don’t like, as simple as that.</p><p>Let us know what you like/dislike!</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=b4b92288e89b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/next-right-now-flexible-production-grade-boilerplate-for-building-web-apps-monorepo-with-b4b92288e89b">Next Right Now — Flexible production-grade boilerplate for building web apps (monorepo), with…</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Unly Releases an Open Source Software for “Airtable Managed backups”]]></title>
            <link>https://medium.com/unly-org/unly-releases-an-open-source-software-for-airtable-managed-backups-919fbdba2a3b?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/919fbdba2a3b</guid>
            <category><![CDATA[open-source-software]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[airtable]]></category>
            <category><![CDATA[remote-backups]]></category>
            <category><![CDATA[aws]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Sat, 11 Jan 2020 21:17:29 GMT</pubDate>
            <atom:updated>2020-01-15T15:30:33.234Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*CMyvzZhFu3RSUk2c.png" /></figure><p>We use Airtable for various things at <a href="https://medium.com/unly-org">Unly</a>, and we have always been concerned by the inability to create scheduled backups that really fit our needs. Despite the fact Airtable has its own backups/restore feature, it didn’t fit our needs.</p><h4>And, because Airtable holds lots of business-sensitive data, it was a very big risk for us not to be in control of the backup&amp;restore process.</h4><p>So, we built a tool that is designed to perform scheduled backups automatically, and deal with backups lifecycle (auto-removal, etc.). Today, we’re releasing this proprietary software as OSS under MIT license.</p><p><a href="https://github.com/UnlyEd/airtable-backups-boilerplate">UnlyEd/airtable-backups-boilerplate</a></p><p>Because backups are very sensitive things, it didn’t make sense to us to build something where we would hold the backups ourselves. <strong>Those are your data</strong>, and in this world controlled by GDPR and alike, nobody likes to give such sensitive information to 3rd parties. So, we built a software <strong>that runs under your AWS Account</strong>, so that you are in control of the whole thing.</p><p>We hope the Airtable community will appreciate such effort, as it is a long-required feature and need that has been asked multiple times across this forum alone.</p><p>Therefore, configuring this software will require some technical skills (AWS), even though everything has been made to make it as simple as possible. (we hate complexity too)</p><p><strong>Regarding pricing</strong>, it is very cheap as it relies on AWS Lambda for the server part (serverless), and AWS S3 for storing the backups themselves. Calculating exactly how much it’s gonna cost is complicated, but because of AWS Free Tiers and because both Lambda and S3 are very cheap, it’s most likely not gonna cost you anything as long as you don’t save Go every hours.</p><blockquote>We use it internally to make backups of 7 Airtable bases on a daily/weekly basis, cost will be $0 for the year. Obviously, it really depends on how often you backup, and how big are your data.</blockquote><p>Let us know what you think about it! :slight_smile:</p><p><em>P.S: Check out </em><a href="https://github.com/unlyEd"><em>https://github.com/unlyEd</em></a><em>, we release lots of things as OSS</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=919fbdba2a3b" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/unly-releases-an-open-source-software-for-airtable-managed-backups-919fbdba2a3b">Unly Releases an Open Source Software for “Airtable Managed backups”</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Universal language detector for JavaScript (browser + nodejs)]]></title>
            <link>https://medium.com/unly-org/universal-language-detector-for-javascript-browser-nodejs-31a271f923a?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/31a271f923a</guid>
            <category><![CDATA[universal]]></category>
            <category><![CDATA[nextjs]]></category>
            <category><![CDATA[i18next]]></category>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[i18n]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Mon, 30 Dec 2019 13:53:57 GMT</pubDate>
            <atom:updated>2020-01-15T15:29:25.153Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/706/1*x5psIY7Uj_PzmAGA8EMTPg.png" /></figure><p>We’ve been working with i18n (internationalization) for a few months, and we couldn’t find any easy way of knowing what’s the user’s language that works both on the browser and on the server.</p><p>There are tons of libs out there, but none that are working universally. So, we decided to outsource our proprietary implementation and release it under MIT license.</p><p>Also, because we’re fans of the Next.js framework, we’ve made an integration example with a demo available there:<br><a href="https://universal-language-detector.now.sh/">https://universal-language-detector.now.sh/</a></p><p><a href="https://github.com/UnlyEd/universal-language-detector">https://github.com/UnlyEd/universal-language-detector</a></p><p>Did you get stuck too with a similar issue when implementing i18n? How did you sort it out? Does this lib help? Let us know! :)</p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=31a271f923a" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/universal-language-detector-for-javascript-browser-nodejs-31a271f923a">Universal language detector for JavaScript (browser + nodejs)</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[How building our own “Typeform to Google Sheets connector” improved our productivity]]></title>
            <link>https://medium.com/unly-org/how-building-our-own-typeform-to-google-sheets-connector-improved-our-productivity-2a902ce3a480?source=rss-3e4790365c74------2</link>
            <guid isPermaLink="false">https://medium.com/p/2a902ce3a480</guid>
            <category><![CDATA[typeform]]></category>
            <category><![CDATA[open-source]]></category>
            <category><![CDATA[lambda]]></category>
            <category><![CDATA[google-sheets]]></category>
            <category><![CDATA[productivity]]></category>
            <dc:creator><![CDATA[Vadorequest]]></dc:creator>
            <pubDate>Tue, 19 Mar 2019 16:42:41 GMT</pubDate>
            <atom:updated>2019-03-21T10:21:18.963Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1000/1*8R5dSP5MTXPXX_opTi4yYw.png" /><figcaption><em>Image credits to </em><a href="https://medium.com/u/1acf1a33f527"><em>Justine Ehrhard</em></a><em> and </em><a href="https://www.integromat.com/en/integrations/google-sheets/typeform"><em>Integromat</em></a></figcaption></figure><h3>How building our own “Typeform to Google Sheets connector” improved our “non-developer” collaborators productivity</h3><blockquote>Empowering collaborators to analyze data from Typeform, without involving developers</blockquote><p><a href="https://www.typeform.com/">Typeform</a> is one of the online services we rely on at <a href="https://www.linkedin.com/company/unly/">Unly</a>, but they don’t always provide exactly what we need. For instance, we got stuck with the “<em>export to CSV</em>” feature which isn’t customizable enough to our taste and didn’t fit our needs.</p><p>So, we built our own solution by connecting Google Sheet to Typeform API!</p><blockquote>Now, fetching Typeform Responses in sheets and keeping those sheets up-to-date is dead simple and can be done by any collaborator, without relying on developers!</blockquote><h3>The problem</h3><p>When using the native “Export to CSV” feature through Typeform platform, you can’t customize whether you want the sheet’s header to use the “questions labels”, or the “refs”.</p><p>Typeform will export the couple “question: answer”, but doesn’t provide the ability to export “ref: answer”.</p><p>This has been an issue for us because some of our forms have coexisting french and english versions, and we need to combine data to cross-analyze and generate statistics. Since question labels are different between versions, it wasn’t possible to cross the data, <strong>that’s what refs are for</strong>.</p><blockquote>Also, <strong>refs</strong> are useful in many other situations. <br>Anytime we had to connect Typeform to other tools, we experienced that we needed refs, because they were the only way to uniquely identify a question. In complex forms, we often end up with multiple identical question labels and tools like Data Studio can’t handle that.</blockquote><blockquote>Using tools like Zapier has similar limitations, because those limitations come from Typeform itself</blockquote><h3>The solution</h3><p>We put this very simple example together so you can experience the complete workflow, from filling the form up to analyzing the results.</p><h4>Everything starts with a form…</h4><p>Start with filling the form, to see your responses added to the spreadsheet in real-time: <a href="https://fsf-sl.typeform.com/to/mJhgzI">https://fsf-sl.typeform.com/to/mJhgzI</a></p><blockquote>Don’t hesitate to leave out a comment if you’re interested by an open source release of our connector!</blockquote><h4>Understanding how the Google Sheet works:</h4><p>Now that you <a href="https://fsf-sl.typeform.com/to/mJhgzI">filled the form</a>, you should see your answers <a href="https://docs.google.com/spreadsheets/d/17OG80QA8oNbomlkKhj0XS16oI9lXaPaIYTBV2x0wihI"><strong>in the sheet</strong></a>.</p><blockquote>If you want to quickly understand how to configure the sheet, then check out the “<a href="https://docs.google.com/spreadsheets/d/17OG80QA8oNbomlkKhj0XS16oI9lXaPaIYTBV2x0wihI/edit#gid=614587251">Settings</a>” and “<a href="https://docs.google.com/spreadsheets/d/17OG80QA8oNbomlkKhj0XS16oI9lXaPaIYTBV2x0wihI/edit#gid=1126687346">API Documentation</a>”. Most of it is explained there!</blockquote><p>The Google Sheet data are configured to refresh upon page refresh. There is no auto-refresh configured here, because it doesn’t make sense for this demo.</p><blockquote>Check out <a href="https://medium.com/unly-org/how-to-consume-any-json-api-using-google-sheets-and-keep-it-up-to-date-automagically-fb6e94521abd">this tutorial</a> if you want to know more about how the sheet works (auto-refresh, API fetching, etc.), and play around with it</blockquote><p><a href="https://medium.com/unly-org/how-to-consume-any-json-api-using-google-sheets-and-keep-it-up-to-date-automagically-fb6e94521abd">How to consume any JSON API using Google Sheets, and keep it up-to-date automagically</a></p><h4>Typeform Ref Editor</h4><figure><img alt="" src="https://cdn-images-1.medium.com/max/713/1*mAaRYGVAQG87g3kIbsPyvQ.png" /><figcaption>Typeform Ref Editor</figcaption></figure><p>If you wonder how we customised our “refs”, <a href="https://tf-edit-ref.glitch.me/">check out this tool</a>, that’s what we use!</p><p><em>(</em><a href="https://medium.com/@Vadorequest/one-good-reason-not-to-use-typeform-9e974df5b22"><em>until TypeForm releases a proper way of doing so</em></a><em>)</em></p><h4>Here are a few handy features provided by our connector</h4><ul><li><strong>No limit of responses fetched</strong>: Typeform API allows only 1000 responses to be fetched at once, but there is no such limit when using our connector!</li><li><strong>CSV-friendly</strong>: Typeform API isn’t CSV friendly, but our connector is! The outputData can be customised to fetch data as csv (for Google Sheet usage), or raw (for other usages), or both (for debug, usually).</li><li><strong>Unique “value” key</strong>: Typeform API use many different keys for storing the value, based on the type of the data, we only use one, which is much simpler to use!</li><li><strong>Authentication</strong>: Each form is secured by its own token. The goal is to avoid granting access to all forms from your TypeForm account at once. It is safer.</li><li><strong>Cloud provider agnostic</strong>: Written using the Serverless Framework, we use it on AWS but there isn’t much work to do to make it compatible with any other Cloud Provider. <strong>Very simple to deploy</strong>, if you’d like to deploy your own version on your own infrastructure. <em>(once open-sourced)</em></li></ul><p>Technically, our connector is nothing more than an AWS Lambda function that acts as a proxy between Google Sheets and Typeform API.</p><h4>Pricing</h4><p>Since it’s hosted on a Lambda, it really costs nothing due to the “pay for what you use” design (AKA “on-demand”).</p><blockquote>For instance, considering 5 API call every 5 minutes (auto-refresh), we expect around 50k Lambda invocation over a month, which makes it a bill of… <strong>$0!</strong></blockquote><h4>Limitations</h4><ul><li><strong>Timeout</strong>: The API request can’t run for more than 30 seconds due to AWS API Gateway timeout limit. It’s not really an issue <em>(we experienced about 6 seconds latency when fetching around 1000 responses)</em>, but that’s something to be aware of when fetching forms with a many responses <em>(&gt; 10k)</em>.</li><li><em>Google Sheets itself also has </em><a href="https://gsuitetips.com/tips/sheets/google-spreadsheet-limitations/"><em>its own limit</em></a><em>.</em></li></ul><p>We hope you enjoyed this quick demo! Please let us know if you’d be interested in an open source release!</p><blockquote><strong>P.S</strong>: We may soon implement a way to <strong>merge responses from multiple forms</strong> together, when exporting them (use case: grouping responses from different forms sharing common refs together, when using localised forms for instance!)<br>Would that interest you as well? <strong>Let us know!</strong></blockquote><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=2a902ce3a480" width="1" height="1" alt=""><hr><p><a href="https://medium.com/unly-org/how-building-our-own-typeform-to-google-sheets-connector-improved-our-productivity-2a902ce3a480">How building our own “Typeform to Google Sheets connector” improved our productivity</a> was originally published in <a href="https://medium.com/unly-org">Unly.org</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>