<?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 Ohans Emmanuel on Medium]]></title>
        <description><![CDATA[Stories by Ohans Emmanuel on Medium]]></description>
        <link>https://medium.com/@ohansemmanuel?source=rss-aea1cff96976------2</link>
        <image>
            <url>https://cdn-images-1.medium.com/fit/c/150/150/1*ptyYiK5FMujk8Gy4VkQT6A.jpeg</url>
            <title>Stories by Ohans Emmanuel on Medium</title>
            <link>https://medium.com/@ohansemmanuel?source=rss-aea1cff96976------2</link>
        </image>
        <generator>Medium</generator>
        <lastBuildDate>Sat, 14 Nov 2026 04:28:23 GMT</lastBuildDate>
        <atom:link href="https://medium.com/@ohansemmanuel/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[Why OpenAI’s Move to Skills Matters If You’re Shipping AI Agents]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@ohansemmanuel/why-openais-move-to-skills-matters-if-you-re-shipping-ai-agents-201d5db54cc2?source=rss-aea1cff96976------2"><img src="https://cdn-images-1.medium.com/max/600/1*zU2svM3JderZjq7nd8LKkg.png" width="600"></a></p><p class="medium-feed-snippet">The best practices for building predictable AI agents are changing</p><p class="medium-feed-link"><a href="https://medium.com/@ohansemmanuel/why-openais-move-to-skills-matters-if-you-re-shipping-ai-agents-201d5db54cc2?source=rss-aea1cff96976------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@ohansemmanuel/why-openais-move-to-skills-matters-if-you-re-shipping-ai-agents-201d5db54cc2?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/201d5db54cc2</guid>
            <category><![CDATA[ai-agent]]></category>
            <category><![CDATA[llm]]></category>
            <category><![CDATA[artificial-intelligence]]></category>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Tue, 16 Dec 2025 09:46:09 GMT</pubDate>
            <atom:updated>2025-12-16T09:48:29.033Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[How to Build a Notion-style editor with AI-powered autocompletion]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@ohansemmanuel/how-to-build-a-notion-style-editor-with-ai-powered-autocompletion-dcc0f55126a2?source=rss-aea1cff96976------2"><img src="https://cdn-images-1.medium.com/max/2600/1*6gF0N0xOxNruOAZ08pfbug.png" width="3810"></a></p><p class="medium-feed-snippet">TLDR: In this essay, we will explore a high-level design of Potion &#x2014;a Notion-style email builder with AI-powered autocompletion. Also, I&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/@ohansemmanuel/how-to-build-a-notion-style-editor-with-ai-powered-autocompletion-dcc0f55126a2?source=rss-aea1cff96976------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@ohansemmanuel/how-to-build-a-notion-style-editor-with-ai-powered-autocompletion-dcc0f55126a2?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/dcc0f55126a2</guid>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Wed, 03 Apr 2024 14:55:53 GMT</pubDate>
            <atom:updated>2024-04-04T02:26:53.561Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Build powerful React forms with Informed]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@ohansemmanuel/build-powerful-react-forms-with-informed-c89e4ccce285?source=rss-aea1cff96976------2"><img src="https://cdn-images-1.medium.com/max/600/1*gcAezKBKtwJIWubB2rgx_w.png" width="600"></a></p><p class="medium-feed-snippet">Forms are a staple of web development. If you must collect user input on the web and process these on your server, you need a form.</p><p class="medium-feed-link"><a href="https://medium.com/@ohansemmanuel/build-powerful-react-forms-with-informed-c89e4ccce285?source=rss-aea1cff96976------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@ohansemmanuel/build-powerful-react-forms-with-informed-c89e4ccce285?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/c89e4ccce285</guid>
            <category><![CDATA[typescript]]></category>
            <category><![CDATA[react]]></category>
            <category><![CDATA[web]]></category>
            <category><![CDATA[web-development]]></category>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Fri, 17 Feb 2023 20:32:03 GMT</pubDate>
            <atom:updated>2023-03-20T10:13:59.456Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[Are strongly typed functions as parameters possible in TypeScript?]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@ohansemmanuel/are-strongly-typed-functions-as-parameters-possible-in-typescript-2d3fcb2f23ce?source=rss-aea1cff96976------2"><img src="https://cdn-images-1.medium.com/max/2400/1*0atyP182eWQau5i2aA4YDw.png" width="2400"></a></p><p class="medium-feed-snippet">TLDR: This question does not need to be overly explained. The short answer is yes. Functions can be strongly typed parameters</p><p class="medium-feed-link"><a href="https://medium.com/@ohansemmanuel/are-strongly-typed-functions-as-parameters-possible-in-typescript-2d3fcb2f23ce?source=rss-aea1cff96976------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@ohansemmanuel/are-strongly-typed-functions-as-parameters-possible-in-typescript-2d3fcb2f23ce?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/2d3fcb2f23ce</guid>
            <category><![CDATA[typescript]]></category>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Thu, 07 Jul 2022 18:58:23 GMT</pubDate>
            <atom:updated>2022-07-07T18:58:23.549Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[How do you explicitly set a new property on ‘window’ in Typescript?]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@ohansemmanuel/how-do-you-explicitly-set-a-new-property-on-window-in-typescript-e144cfecf8e7?source=rss-aea1cff96976------2"><img src="https://cdn-images-1.medium.com/max/2400/1*AmI4mOhjkJqGP559RBjyTw.png" width="2400"></a></p><p class="medium-feed-snippet">TLDR: Extend the existing interface declaration for the `Window` object</p><p class="medium-feed-link"><a href="https://medium.com/@ohansemmanuel/how-do-you-explicitly-set-a-new-property-on-window-in-typescript-e144cfecf8e7?source=rss-aea1cff96976------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@ohansemmanuel/how-do-you-explicitly-set-a-new-property-on-window-in-typescript-e144cfecf8e7?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/e144cfecf8e7</guid>
            <category><![CDATA[typescript]]></category>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Thu, 07 Jul 2022 16:49:51 GMT</pubDate>
            <atom:updated>2022-07-07T16:50:06.183Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[What is a “.d.ts” file in TypeScript?]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@ohansemmanuel/what-is-a-d-ts-file-in-typescript-2e2d90d58eca?source=rss-aea1cff96976------2"><img src="https://cdn-images-1.medium.com/max/2400/1*UevheogF8D7PIadKdbSd2Q.png" width="2400"></a></p><p class="medium-feed-snippet">.d.ts files are called type declaration files. They exist for one purpose only: to describe the shape of an existing module and they only</p><p class="medium-feed-link"><a href="https://medium.com/@ohansemmanuel/what-is-a-d-ts-file-in-typescript-2e2d90d58eca?source=rss-aea1cff96976------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@ohansemmanuel/what-is-a-d-ts-file-in-typescript-2e2d90d58eca?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/2e2d90d58eca</guid>
            <category><![CDATA[typescript]]></category>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Thu, 07 Jul 2022 16:27:46 GMT</pubDate>
            <atom:updated>2022-07-07T16:27:46.950Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[In Typescript, what is the ! (exclamation mark / bang) operator?]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@ohansemmanuel/in-typescript-what-is-the-exclamation-mark-bang-operator-6bf41ab4f97e?source=rss-aea1cff96976------2"><img src="https://cdn-images-1.medium.com/max/2400/1*hpPAkvj5bF-mICaNUxwvFQ.png" width="2400"></a></p><p class="medium-feed-snippet">TLDR</p><p class="medium-feed-link"><a href="https://medium.com/@ohansemmanuel/in-typescript-what-is-the-exclamation-mark-bang-operator-6bf41ab4f97e?source=rss-aea1cff96976------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@ohansemmanuel/in-typescript-what-is-the-exclamation-mark-bang-operator-6bf41ab4f97e?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/6bf41ab4f97e</guid>
            <category><![CDATA[typescript]]></category>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Thu, 07 Jul 2022 15:39:51 GMT</pubDate>
            <atom:updated>2022-07-07T15:39:51.420Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[The React Hooks API reference — easy-to-read (visual) version]]></title>
            <description><![CDATA[<div class="medium-feed-item"><p class="medium-feed-image"><a href="https://medium.com/@ohansemmanuel/the-react-hooks-api-reference-easy-to-read-visual-version-479cc23f670f?source=rss-aea1cff96976------2"><img src="https://cdn-images-1.medium.com/max/600/1*6PB-QyeOpXDNUkqShkgifQ.png" width="600"></a></p><p class="medium-feed-snippet">React hooks were added to React in version 16.8. With the transition from class to functional components, hooks let you use state and&#x2026;</p><p class="medium-feed-link"><a href="https://medium.com/@ohansemmanuel/the-react-hooks-api-reference-easy-to-read-visual-version-479cc23f670f?source=rss-aea1cff96976------2">Continue reading on Medium »</a></p></div>]]></description>
            <link>https://medium.com/@ohansemmanuel/the-react-hooks-api-reference-easy-to-read-visual-version-479cc23f670f?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/479cc23f670f</guid>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Sun, 26 Jun 2022 05:38:46 GMT</pubDate>
            <atom:updated>2022-06-26T05:38:46.435Z</atom:updated>
        </item>
        <item>
            <title><![CDATA[What is Typescript?]]></title>
            <link>https://medium.com/@ohansemmanuel/i-published-an-intermediate-typescript-and-react-handbook-a-few-weeks-ago-6994340864cf?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/6994340864cf</guid>
            <category><![CDATA[javascript]]></category>
            <category><![CDATA[typescript]]></category>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Sun, 26 Jun 2022 05:27:46 GMT</pubDate>
            <atom:updated>2022-06-26T05:28:33.652Z</atom:updated>
            <content:encoded><![CDATA[<figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*NulhccAWL_wNcwHw.png" /><figcaption>What is Typescript?</figcaption></figure><p>I published an <a href="https://www.ohansemmanuel.com/books/how-to-build-strongly-typed-polymorphic-react-components">Intermediate Typescript and React Handbook</a> a few weeks ago.</p><p>It received numerous views and I got several emails. Most were “thank you” emails, but then there were others like:</p><blockquote><em>“… I am new to programming, what is Typescript?”</em></blockquote><blockquote><em>“Thanks for this free ebook, but how do I learn Typescript as a beginner?”</em></blockquote><p>I had clearly stated that the handbook was for intermediate developers who already knew some Typescript — but when did that ever stop anyone from downloading a free resource! :)</p><p>In this guide, I’ve decided to answer the queries in those emails with the article I wish I had when I learned Typescript.</p><p>Now, if you’re still reading, I’ll assume you’re a Typescript beginner.</p><p>Strap up. You’re in for a fun ride.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/800/0*H_x7Q7Ued1i-Cx1D.png" /><figcaption>GIF by Jona Dinges (https://dribbble.com/jonadinges)</figcaption></figure><h3>Explaining Typescript to a 5-year-Old</h3><p>My approach to teaching has always remained the same.</p><p>If you can’t explain it to a 5-year-old, you may not know the subject well enough.</p><p>Instead of swarming you with a lot of technical jargon, let’s try something different.</p><p>Let’s use an analogy you’ll never forget.</p><p>When was the last time you visited the grocery store?</p><p>Consider TypeMart:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*g2kPJLapi9uQiy-J.png" /><figcaption>The Typemart grocery store</figcaption></figure><p>TypeMart is your typical <strong>big</strong> grocery store.</p><p>Do you want a variety of grocery items picked up after work? They’ve got you covered.</p><p>On the other hand, here’s JMart:</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*9EVq0MVtTFmynibN.png" /><figcaption>The Jmart grocery store</figcaption></figure><p>JMart is a smaller grocery store for quick purchases.</p><p>In Berlin, where I live, we call these <a href="https://allaboutberlin.com/glossary/Sp%C3%A4ti#:~:text=A%20Sp%C3%A4ti%20or%20Sp%C3%A4tkauf%20(pronounced,and%20bodegas%20in%20other%20countries.">Spätis</a>. These are essentially small convenience shops.</p><p>I’m sure you’re not here for a German lesson.</p><p>What’s important to us here is how the grocery stores, JMart and TypeMart work.</p><h3>How JMart and TypeMart work</h3><p>With <em>JMart</em>, you go into the shop, find the grocery item you need and take it to the cashier.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*gko-Gvnqj_QWey_M.png" /><figcaption>Wondering how much your total purchase costs</figcaption></figure><p>At this point, you’re not quite sure how much the grocery item you’ve picked costs.</p><p>Well, that’s why you go to the cashier!</p><p>The cashier takes your item, scans it and tells you how much it cost.</p><p>If they’re “better” at their job, they’ll tell you how much the item cost off the top of their head (or some manual catalogue they keep in the drawer)</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*OamXdbhRfvF8vd-b.png" /><figcaption>Receiving the sum of goods from the cashier</figcaption></figure><p>The process seems brittle, but boy does it work!</p><p>These cashiers are smart as hell. No items are off-limits.</p><p>They know what every item costs.</p><p>One beautiful Tuesday, you decide to try out <em>TypeMart</em>.</p><p>You soon realise that things are different in TypeMart.</p><p><em>’Those pesky big stores,’</em> you may say.</p><p>Unlike JMart, they’ve got a price tag for every damn thing.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*mbk9Q3iCgJBsP0PX.png" /><figcaption>Price labels on baskets of fruits</figcaption></figure><p>They rob you of the thrill and the look on the cashier’s face as they compute your bill.</p><p>On the other hand, what they give you is some sort of assurance.</p><p>There are no surprises!</p><p>You know exactly how much every item you’ve picked up costs.</p><p>That is beneficial on days when your wallet is slim.</p><p>Every pence matter.</p><h3>Why does this analogy matter?</h3><p>Your intuition was correct.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*S_RY8XpZXG3K0bq3.png" /><figcaption>JMart represents Javascript, and Typemart, Typescript</figcaption></figure><p>In the analogy, JMart represents Javascript and TypeMart, Typescript.</p><p>When you go to a supermarket, there’s an unwritten contract.</p><p>They promise to have what you need at a fair price.</p><p>You promise to pay for what you buy (except you’re shoplifting. Don’t do this.)</p><p>The same is true for code.</p><p>It’s an unwritten contract, but a clear and brutal one.</p><p>Your contract is with the user of your application.</p><p>You promise that your application works.</p><p>Consider an example with a conference call application like Google meet.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Jpq-kUPPQ-QTSLvl.png" /><figcaption>The Google meet web interface</figcaption></figure><p>The promise with Google meet is you’ll always be able to make video calls. They also promise you can mute the button while you chat with your partner or watch a quick TikTok.</p><p>Good thing they can’t hear you!</p><p>Or, so you think?</p><p>Imagine if the mute button didn’t do what it promised.</p><p>There goes your secret.</p><p>And with it goes your trust in Google meet.</p><p>The same is true for the applications you write.</p><p>You promise a working application, and your users trust that’s the case — assuming you’ve earned their trust.</p><p>Let’s now bring this home.</p><p>In JMart and TypeMart, the goods are money. With software, the goods are data.</p><p>Assume you had a basic counter application.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*xqMUppTAvdbvDg6x.png" /><figcaption>A basic counter application</figcaption></figure><p>Your user sees a fancy UI, but under the hood what’s really making magic is the counter <em>variable</em> you increase or decrease.</p><p>With JMart (analogous to Javascript), the goods are not labelled (price tagged). You don’t know how much anything costs. You go to the cashier to meet your fate.</p><p>This is similar to how Javascript works.</p><p>You define and manipulate all sorts of variables, but there’s no explicit label for what the variables are.</p><p>You trust what you’ve written and pass it on to the Javascript compiler to meet your fate.</p><p>Consider the following trivial Javascript code:</p><p>In a standard Javascript application, you may go-ahead to write the following:</p><p>Even though cars does not exist on the JMArt object, there’s no explicit label that defines that.</p><p>So, as you write your code, you may not know this line of code is faulty …</p><p>Until you go to the cashier to meet your fate.</p><p>The cashier here is the Javascript interpreter.</p><p>Typically, this happens when you run the code in a browser.</p><p>If you do, you then get an error that reads can&#39;t read price of undefined</p><p>If you shipped this code (mistakenly) to production, your uses will be met with this ugly error as well.</p><p>You’ve just compromised their trust in your application.</p><p>With Typescript, things are different.</p><p>Every data is “labelled” just like in TypeMart.</p><p>Before you go to the cashier aka the browser to run the code, you can tell if your application is working as it should!</p><p>The Typescript compiler will throw an error letting you know you’ve made a mistake accessing a wrong value.</p><p>This happens within your code editor before you open the application in a browser.</p><p>Like picking up a grocery item you can’t afford at TypeMart, you see the price label.</p><p>You know what’s in your wallet. It’s fair to say you’ve been warned.</p><p>This right here is the major initial definition of Typescript you should know.</p><blockquote><em>TypeScript is JavaScript with syntax for types.</em></blockquote><p>Where types are labels dangling around your grocery item (data), telling you exactly what each data represents.</p><p>Consider the following trivial Javascript example:</p><p>In Typescript, this code could look like this:</p><p>Note how this looks identical to the Javascript code.</p><p>However, it’s got a major difference: the data a and b are &#39;labelled&#39;.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*aVLeouGMV61qlUrf.png" /><figcaption>Typescript types AKA labels</figcaption></figure><p>This code specifically states that a and b expected in myFunction are strings.</p><p>With this information (called type annotation), Typescript can now show you errors as you write your code.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*na8lKlVfbE1AlQHT.png" /><figcaption>Typescript errors highlighted</figcaption></figure><p>These errors will usually be seen in the form of red squiggly lines. Similar to errors in applications like Microsoft Word.</p><p>You may then hover over these lines to view the details of the error.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*c9YciH3XN4DcB75f.png" /><figcaption>The details of the Typescrit error</figcaption></figure><p>In this simple example, the crux of the error is that the multiplication operation should not be run on strings.</p><h3>Non-exception errors</h3><p>If you’re a more experienced Javascript developer, you can already notice that the code example earlier examined doesn’t throw an error in standard Javascript.</p><p>If you computed “1” * &quot;6&quot; in Javascript, you’ll get 6.</p><p>Internally, Javascript coerces the strings to numbers and performs the multiplication operation.</p><p>These sorts of errors that don’t fail in Javascript, but error out in Typescript, are called non-exception errors.</p><p>These are supposed to help you prevent nasty bugs in your application.</p><p>You shouldn’t necessarily worry about this at this stage of your learning Typescript journey, but it’s worth mentioning.</p><p>As you can see, Typescript goes far and beyond to help you catch unwanted behaviours in your code.</p><p>A simple way to fix this would be to type the parameters explicitly, i.e., a and b as numbers:</p><p>And away goes the error!</p><p>Don’t despite Typescript for bringing these non-exception errors to your attention.</p><p>They are potential sources of bugs in your application.</p><p>Typescript to the rescue 💪🏽</p><h3>Conclusion</h3><p>Ask yourself, do I now know what Typescript is?</p><p>Yes, you do. Conceptually.</p><p>Typescript is to Javascript what TypeMart is to JMart.</p><p>An organised way to <em>label</em> the data within your application to prevent unknown errors.</p><p>These errors will be caught and brought to your attention before you go to the cashier, i.e., before you run your application.</p><p>Take a moment to digest this information. It’ll be crucial as you learn more about Typescript.</p><p>Give yourself a pat on the back, and go write your first Typescript application.</p><h3>Further Resources</h3><ul><li><a href="https://www.ohansemmanuel.com/books/how-to-build-strongly-typed-polymorphic-react-components">Intermediate TypeScript and React Handbook</a>: Learn intermediate Typescript with React by building a strongly typed Polymorphic component.</li></ul><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*igkbOxDpLrQLewhU.png" /><figcaption>Lear intermediate Typescript with this free book</figcaption></figure><ul><li>Fancy a quick Typescript exercise? Spot and fix the error in the earlier described example. Use the official online editor called the Typescript playground here: [<a href="https://shrtm.nu/FlC0">https://shrtm.nu/FlC0</a>]</li></ul><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=6994340864cf" width="1" height="1" alt="">]]></content:encoded>
        </item>
        <item>
            <title><![CDATA[Google Ads and React.js: Delivering Ads with a Great UX]]></title>
            <link>https://engineering.omio.com/google-ads-and-react-js-delivering-ads-with-a-great-ux-c18406ee71ee?source=rss-aea1cff96976------2</link>
            <guid isPermaLink="false">https://medium.com/p/c18406ee71ee</guid>
            <category><![CDATA[reactjs]]></category>
            <category><![CDATA[native-advertising]]></category>
            <category><![CDATA[software-development]]></category>
            <category><![CDATA[tech]]></category>
            <category><![CDATA[technology]]></category>
            <dc:creator><![CDATA[Ohans Emmanuel]]></dc:creator>
            <pubDate>Mon, 09 Dec 2019 14:15:19 GMT</pubDate>
            <atom:updated>2019-12-09T15:21:40.022Z</atom:updated>
            <content:encoded><![CDATA[<p>How to run on-site advertising that provides a seamless experience leveraging your company’s component libraries.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*MSLLmoZ32T27GfO1" /></figure><p>Since the inception of online advertising, users have always complained about the design and relevancy of ads. With the nature of business being to aim for maximum visibility, there is always a dissonance between attention and readability of a website’s content.</p><p>As we all know, contrary to print media, there are virtually no technical limitations on the web when it comes to the visual appearance of an ad. Display units in specific have reached a state where some are so extremely annoying that certain committees are even discussing standards for acceptable ads.</p><h3>Native Ads to the Rescue</h3><p>Our generation has mastered the art of ignoring such content and the industry has largely caught up on that. Native ads is one of the least invasive measures that fit a publisher’s web experience.</p><p>The idea is stunningly simple: Instead of marketing out differently styled content on your website (with overlays and blinking banners probably being the most annoying manifestation of their species), you get to decide what an ad unit looks like. It is then up to the advertiser to provide a copy, among other creatives. Not only is it visually less disturbing — by sharing your app’s look and feel, but a native ad is also very likely to exhibit a better click-through rate.</p><h3>Native Ads: A Quick Example</h3><p>To give a quick peek on what Omio’s ad product looks like, have a look at the screenshot below. The ad is distinguishable from the rest of the content both by bearing the “sponsored” label and less functionality compared to the remainder of the result cells.</p><p>But it shares the same style and is built using the same frontend components as the rest of the page.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/675/0*eOyPi7Nv1nJmWtzF" /></figure><p>The native ad is intuitive and blends with the entire user experience of the product. If the “sponsored” text wasn’t present, you’d never recognise that result as an ad.</p><h3>5 Reasons the Status Quo wasn’t enough for us.</h3><p>Generally speaking, serving ads is implemented by following a pretty standard procedure. If you’re running a website, adding a small piece of javascript code is more than enough to get you up and running. If you want to spice things up a little you can use an ad manager to enjoy sophisticated targeting rules.</p><p>Initially, this was pretty much the path we chose to go down as well. Our baseline setup contained an ad slot in our React frontend which was remotely managed by Google AdManager. With as little as some HTML &amp; CSS and some targeting rules based on the user’s search terms, our team was able to run ads on page.</p><p>Even though this worked for our first iteration, it just didn’t feel right for a number of reasons.</p><h3>1.Crafting Pixel Perfect Designs</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*B7-mBwHyk25Do-dx" /></figure><blockquote>Building pixel-perfect designs isn’t a superfluity or after-thought. It is to serve the user.</blockquote><p>This core value is etched deeply into every product we develop — and the implementation of native ads by mixing some basic HTML and CSS in a confined editor seemed to be doing an injustice to our design philosophy.</p><p>Our design team has spent countless hours running user research and building a design system that serves as a common language for all teams in the company. This keeps the entire organization (with a diverse group of teams) on the same page. By leveraging our design system, teams can move faster, communicate better and ultimately increase the speed at which products are released without compromising pixel-perfect designs.</p><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ICIbvzCMjFwe9DbY" /><figcaption><em>Dotty — our internal design system.</em></figcaption></figure><p>For engineers, a big part of a design system is a library of frontend components. It is more challenging to create perfectly designed native ads without taking advantage of an already established library of components built to reflect a consistent representation of our brand message. A component library not just provides us with pixel-perfect designs, but greatly increases the speed at which we ship ads without having to reinvent the wheel.</p><p>More so, when everyone speaks the same language, things get done faster. As a company, a component library lets us speak the same language. Yes, with gruesome engineering hours, we might end up re-creating near-perfect Ads with a WYSIWYG editor, but by completely neglecting our component library, we would be disconnected from speaking the same language as everyone else in the entire company.</p><p>To sum up our thoughts on creating pixel-perfect designs, our goal here was to build ads with a great user experience and to do so without breaking the internal means of communication we hold highly within the company — a consistent design system built to promote pixel-perfect designs. This means reusing our frontend component library and delivering a consistent user experience across the entire user funnel, every single time.</p><h3>2. Speed of Iterations</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*Z2Vjy66BryMfPGpj" /></figure><p>Iterative and user-data-driven development of software is highly encouraged here at <a href="http://www.omio.com/">Omio</a>, and as such we’ve built pipelines and processes that enable teams to move fast across the entire company.</p><blockquote>Delivering highly performant ads require a lot of tests and iterations to run successful campaigns.</blockquote><p>For example, if we went with using the typical WYSIWYG solution, a simple A/B test fostered by a change in design will require communicating with our Ad ops to implement the new design and also tweak the ad campaign set up. This isn’t very efficient.</p><p>A more solid approach would be to let our frontend engineers take care of the design implementation, connect this with our A/B test service and letting our Ad ops focus solely on managing the ad campaign. This breeds a division of labour and specialization among the engineering and ad ops teams. All engineering efforts are centralised within the engineering team and the planning, execution, tracking and analytics of the ad campaign is managed solely by the Ad ops team.</p><p>This sort of separation of concerns weeds out unnecessary dependencies between teams, a common source of friction when building any product. This leads to faster ads development and release cycles.</p><h3>3. Versioning and Using a Single Tech Stack</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*KxB1T1XdUbCkceue" /></figure><p>With a WYSIWYG editor, your options are limited. You write some HTML and CSS, and for writing Javascript, you’re confined to writing scripts within the script tag of an HTML panel.</p><p>What if your team had spent time building a thriving ecosystem around a specific modern tech stack? A stack that includes release pipelines, preview functionality, modern development experience, and embraces a set of standards and best practices?</p><p>As a company, our frontend stack relies on <strong>React</strong> for creating delightful user experiences. No engineer should be forced to write HTML, and CSS in a WYSIWYG editor when we’ve built a solid infrastructure around our tech stack.</p><blockquote>The benefits you get from using a modern tech stack likely outweighs what’s offered by WYSIWYG editors in an ad manager.</blockquote><p>Now consider versioning, an integral process in the way software is developed today. When you have multiple developers working on a single application, as is the case in most notable projects, it’s almost impossible to prevent developers from overwriting code changes and breaking each other’s code without a solid versioning system.</p><p>With modern versioning systems, a developer can download the current version of the project, work locally and merge their changes without stepping on another developer’s toes. This is important as you can deploy varying versions to different environments such as QA and production, and also work locally in confidence that you’re aren’t jeopardising your colleague’s efforts.</p><p>These were strong considerations while designing and planning our native ads implementation. It doesn’t matter what technology stack you use, these concerns remain potent.</p><p>We believe that building well-implemented native ads doesn’t mean kicking your current tech stack and development processes out of the window or compromising on a simple yet integral process such as versioning.</p><h3>4. Internationalization</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*jw3XklfiZK4-tzW1" /></figure><p>When building a global brand, the internationalization of your products is important. It could very well influence the acceptance of your product offering.</p><p>If your app / website is available only in English language, you will be cutting off the opportunity to tap into potentially larger foreign markets.</p><blockquote><em>86%</em> of localized campaigns have been <a href="http://www.oneskyapp.com/blog/14-compelling-statistics-about-the-importance-of-localization/">found to outperform</a> English campaigns in both click-throughs and conversions.</blockquote><p>Internationalization is not a trivial requirement. You need correct translations (preferably by experts/natives), and you need to create a process for which your engineers and copywriters can stay in sync on these translations. For most companies, a process has been tested and currently serves the need of your website/app Internationalization.</p><p>Here at <a href="https://www.omio.com/">Omio</a>, we’ve built a process that leverages <a href="http://phraseapp.com/">PhraseApp</a> service which provides us with instantaneous updates. With internationalization being a core requirement for our product offering, it goes without saying that this was a huge requirement for our native ads as well.</p><p>How do you make sure that copywriting and translations are seamlessly integrated into the ad development experience? How do you also ensure that instantaneous updates are received as soon as translations are updated? Most ad manager editors just don’t provide the same level of confidence, communication and reliability you get from a standardized internationalisation process. Regardless of your current internationalization process, you’ll most likely spend ample engineering hours if you tried to replicate this within the confines of an ad manager.</p><h3>5. Sharing context between the Ad and the Website</h3><figure><img alt="" src="https://cdn-images-1.medium.com/max/1024/0*ChzmZY_wskT4KbKJ" /></figure><p>Naturally, most ads do not interact with the page itself. They either open a new window or perform a whole page reload once being clicked on.</p><p>Hence, one requirement we put on ourselves was:</p><blockquote>If our ads are created treated with the same standards as the rest of our product, they should behave like it.</blockquote><p>This in turn would mean: They are capable of interacting with the page they are placed on, thus providing a seamless user experience.</p><p>Sharing context between a native ad and a parent window sparks interesting engineering challenges.The scope of this article doesn’t permit a full-blown discussion on all the problems encountered and our technical solution to them.</p><p>However, the crux of the challenges stems from the fact that native ads powered by an ad manager are typically rendered within an Iframe, and an iframe possesses inherent security limitations set by every browser.</p><p>A common clause you’d hear within the tech community is: “use the right tool for the job”. While “the right tool” is sometimes subjective, in some cases the choice is based on the ease the tool provides for solving certain engineering challenges.</p><p>For our native ads implementation, we decided we’d have a greater chance of solving this challenge if we used the same tools and services available to us in our day-to-day development processes.</p><p>The reason this was important for us is that our native ads aren’t just made of static images and text. They were designed to be highly interactive with the host page, and this poses even more challenges.</p><p>Doing this outside the comfort of a standard development process would mean solving difficult engineering challenges with unfamiliar tooling provided by an ad manager. While this may not be the wrong call for everyone, in our case, our judgment was based on reusing the tools we already have in place and making sure we were ready to tackle the challenges that’d come from implementing highly interactive native Ads.</p><p>The “right tool for the job” in this case was sticking to tried-and-tested tools we already leverage every day in our day-to-day development. Without going into too much detail, we leveraged the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage">window.postMessage</a> browser API and wired it up with existing redux actions on the frontend. This allowed us to establish a 2-way communication between the iframe and parent. We will post a deep dive into our technical solution in the follow up article.</p><h3>What’s next?</h3><p>So far we have seen great initial results which have proven that our users really like interacting with our native ads. Seeing that our tech and product work has paid out is encouraging for us as a team and we will see how we can scale the approach from hereon.</p><p>In the next segment we will shed more light on the technical details and the overall setup of the system, so watch this space for the next segment of ads with a great UX!</p><p>~</p><p><em>Enjoyed the read? </em><a href="http://www.omio.com/"><em>Omio</em></a><em> is hiring! If you would like to be part of our team and solve great problems, make sure you visit our </em><a href="https://www.omio.com/jobs/"><em>jobs page</em></a><em> and follow us on Medium.</em></p><img src="https://medium.com/_/stat?event=post.clientViewed&referrerSource=full_rss&postId=c18406ee71ee" width="1" height="1" alt=""><hr><p><a href="https://engineering.omio.com/google-ads-and-react-js-delivering-ads-with-a-great-ux-c18406ee71ee">Google Ads and React.js: Delivering Ads with a Great UX</a> was originally published in <a href="https://engineering.omio.com/">Omio Engineering</a> on Medium, where people are continuing the conversation by highlighting and responding to this story.</p>]]></content:encoded>
        </item>
    </channel>
</rss>