<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Hussein Al Hammad</title>
    <description>The latest articles on DEV Community by Hussein Al Hammad (@hus_hmd).</description>
    <link>https://dev.to/hus_hmd</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F53925%2F3882a6ff-be8f-46cf-bd7b-49e74cf5447e.jpg</url>
      <title>DEV Community: Hussein Al Hammad</title>
      <link>https://dev.to/hus_hmd</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/hus_hmd"/>
    <language>en</language>
    <item>
      <title>The new Outlook for Windows</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Mon, 13 Mar 2023 17:00:29 +0000</pubDate>
      <link>https://dev.to/emailmarkup/the-new-outlook-for-windows-54k7</link>
      <guid>https://dev.to/emailmarkup/the-new-outlook-for-windows-54k7</guid>
      <description>&lt;p&gt;On 17 May 2022, Microsoft &lt;a href="https://insider.office.com/en-us/blog/the-new-outlook-for-windows-helps-you-be-more-productive-and-in-control-of-your-inbox"&gt;announced the new Outlook for Windows&lt;/a&gt;, a version that will have a huge positive impact in the email space.&lt;/p&gt;

&lt;h2&gt;
  
  
  Now
&lt;/h2&gt;

&lt;p&gt;For years, the Outlook for Windows desktop apps relied on proprietary technology to render HTML emails: their own Microsoft Word. The historic and business reasons behind that decision is not the topic of today, but its impact is.&lt;/p&gt;

&lt;p&gt;Besides proprietary features that only work on Outlook for Windows, the rendering of HTML and CSS features is not always identical to the W3C specification. The Microsoft Word rendering engine had not kept up with the HTML’s living standard.&lt;/p&gt;

&lt;p&gt;The result? Given the wide use of Outlook for Windows globally, email developers stuck with patterns only needed to ensure their HTML emails render well on Outlook for Windows. Because these patterns are not needed for emails to render well elsewhere, it’s an Outlook-first approach and not a user-first one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The new Outlook for Windows
&lt;/h2&gt;

&lt;p&gt;&lt;iframe width="710" height="399" src="https://www.youtube.com/embed/dfWTGgi7xAs"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;The new Outlook for Windows brings a fundamental change. It no longer uses Microsoft Word as a rendering engine, but a normal web browser engine. &lt;/p&gt;

&lt;p&gt;Based on the initial testing of developers in the email community, it is reported to have an almost identical handling of HTML/CSS features to the web version of Outlook. This aligns with Microsoft’s goal to “bring consistency across our Windows and web codebases”. &lt;/p&gt;

&lt;p&gt;It has been a multi-year effort to reach this point, and Microsoft has been &lt;a href="https://techcommunity.microsoft.com/t5/video-hub/the-evolution-of-outlook/ba-p/1681527"&gt;betting on web technologies&lt;/a&gt; when developing new features for their Outlook apps across all operating systems for some time now. Finally, it’s now time for the HTML rendering to catch up with the rest of the app.&lt;/p&gt;

&lt;h2&gt;
  
  
  Availability
&lt;/h2&gt;

&lt;p&gt;At the time of the announcement:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;The new Outlook for Windows is available to Beta Channel users running Version 2205 (Build 15225.20000) or later.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;However, it seems Microsoft is making the new version more accessible to more users as it can be downloaded and installed via its &lt;a href="https://apps.microsoft.com/store/detail/outlook-for-windows/9NRX63209R7B"&gt;Windows App store&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The path forward
&lt;/h2&gt;

&lt;p&gt;“Code like it’s the 90s” - an eternal joke that is reaching its expiry date. &lt;a href="https://learn.microsoft.com/en-us/lifecycle/products/?terms=Outlook"&gt;October 2026&lt;/a&gt; is the month when Microsoft is ending support to the last version of Outlook that uses the Microsoft Word rendering engine. We can anticipate users to start using the new Outlook for Windows well before that date.&lt;/p&gt;

&lt;p&gt;The step Microsoft is taking here makes the goal of enforcing some email standards more feasible. One of the key reasons we started the Email Markup Consortium &lt;a href="https://dev.to/emailmarkup/introducing-the-email-markup-consortium-emc-52ak"&gt;last year&lt;/a&gt; was we believed the timing is right. This is a huge milestone in the email industry and we believe it is going to help us realize &lt;a href="https://emailmarkup.org/en/docs/vision/"&gt;our vision&lt;/a&gt;.&lt;/p&gt;

</description>
      <category>email</category>
      <category>html</category>
    </item>
    <item>
      <title>电子邮件标记联盟简介 (EMC)</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Wed, 06 Jul 2022 08:41:22 +0000</pubDate>
      <link>https://dev.to/emailmarkup/dian-zi-you-jian-biao-ji-lian-meng-jian-jie-emc-1h09</link>
      <guid>https://dev.to/emailmarkup/dian-zi-you-jian-biao-ji-lian-meng-jian-jie-emc-1h09</guid>
      <description>&lt;p&gt;This post was originally &lt;a href="https://dev.to/emailmarkup/introducing-the-email-markup-consortium-emc-52ak"&gt;published in English&lt;/a&gt;. Translated by &lt;a href="https://twitter.com/muxiangliu"&gt;Muxiang Pajerski&lt;/a&gt;. &lt;/p&gt;




&lt;h2&gt;
  
  
  电子邮件标记联盟是什么？
&lt;/h2&gt;

&lt;p&gt;电子邮件标记联盟 (EMC) 是一个由电子邮件行业内专业人士领导与组织的非营利社区组织，它致力于改善每个人的电子邮件使用与应用的体验。&lt;/p&gt;

&lt;p&gt;发件人、收件人和电子邮件客户端的共同目标是改善用户体验， 并最大程度的优化可达性、功能性、一致性和可靠性。然而，目前致力于达到这些共同目标的电子邮件行业内各环节缺乏合作，导致电子邮件最终在各个电子邮件客户端的结果不一致。&lt;/p&gt;

&lt;p&gt;收件人应该能够轻松访问他们收到的每封电子邮件的内容，无论他们的设备、电子邮件客户端、辅助技术或互联网速度如何。 结合创建与发送电子邮件的工具，电邮标记联盟 (EMC)  与电子邮件程序开发人员及电子邮件各客户端 一起合作，将在电子邮件旅程的每一步推动这一愿景。&lt;/p&gt;

&lt;h2&gt;
  
  
  为什么需要这个联盟？
&lt;/h2&gt;

&lt;p&gt;综上所述，电子邮件业内相关各方缺乏合作来达到实现这些共同目标的愿望。&lt;/p&gt;

&lt;p&gt;EMC 并不是第一个尝试解决这个问题的组织和项目。过去也有一些组织和个人在这方面做出过一些努力，其中包括：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/2007/05/html-mail/html-email-standards"&gt;2007 年电子邮件标准项目&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lists.w3.org/Archives/Public/public-html-mail/2007Feb/"&gt;W3C public-html-mail 邮件列表 2007&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://web.archive.org/web/2014*/Fixoutlook.org"&gt;修复 微软Outlook 2009&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.w3.org/community/htmail/"&gt;电子邮件社区组 2014 的 W3 HTML&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.litmus.com/blog/litmus-microsoft-partnership-update-2017/"&gt;Litmus 微软合作伙伴关系 2016&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;以上证明，相关各方的合作确实存在差距，电子邮件行业需要 EMC 这样的组织与项目来引导相关各方聚集一团，整合资源和力量一起合作达到我们的共同目标。&lt;/p&gt;

&lt;h2&gt;
  
  
  为什么EMC与以前的项目不同？
&lt;/h2&gt;

&lt;p&gt;以前的项目得到过很好的支持，并对推动这个共同目标的进展有所帮助，但是，它们中的大多数目前已经停止了运作。&lt;/p&gt;

&lt;h3&gt;
  
  
  长久性
&lt;/h3&gt;

&lt;p&gt;EMC 的目标之一是长久性。我们计划在运作 EMC当中，在现任各项目的负责人员离开时，该项目仍然能持续进行下去并得到有效的支持。为了实现这一点，我们把这个项目尽可能的开放给大众。所有的工作进程与资源都公开地发布在 GitHub 上，任何人都可以为这个项目贡献他们的专业知识和力量。&lt;/p&gt;

&lt;p&gt;我们还在研究考虑一个长期性解决方案来应对电子邮件标记的持续性与新技术可能带来的新挑战。我们不希望只是短暂性地解决几个小问题，相反，我们致力于电子邮件的标准化与规范化并希望在未来的电子邮件领域里能持续保持这些标准与规范。&lt;/p&gt;

&lt;h3&gt;
  
  
  最佳时机
&lt;/h3&gt;

&lt;p&gt;我们认为与之前的尝试相比，我们这个项目的时机更好。近年来，电子邮件社区大规模发展，各方协作也大大增加。由业内社区志愿者专业人员为社区推出的相关新项目不断涌现，例如庞大的 &lt;a href="https://email.geeks.chat/"&gt;EmailGeeks（电子邮件极客） Slack 组&lt;/a&gt;、&lt;a href="https://womenofemail.org/"&gt;电子邮件专业女性社团&lt;/a&gt;、&lt;a href="https://www.caniemail.com/"&gt;CanIEmail（我能邮件吗）&lt;/a&gt;、&lt;a href="https://howtotarget.email/"&gt;如何针对电子邮件客户端&lt;/a&gt; 等等。&lt;/p&gt;

&lt;h3&gt;
  
  
  有效合作的根据
&lt;/h3&gt;

&lt;p&gt;近年来的电子邮件客户端在 &lt;a href="https://amp.dev/about/email/"&gt;AMP for Email&lt;/a&gt; 等项目上协作并采用 BIMI 等标准证明了在电子邮件领域中相互竞争的各个供应商是可以一起合作的。&lt;/p&gt;

&lt;h2&gt;
  
  
  志愿者如何参与？
&lt;/h2&gt;

&lt;p&gt;该项目是开源项目，你可以在 &lt;a href="https://github.com/email-markup-consortium"&gt;GitHub&lt;/a&gt; 上找到我们，任何人都可以贡献一份力量：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  您可以&lt;a href="https://github.com/email-markup-consortium/email-markup-consortium/discussions"&gt;即刻加入并参与现有的讨论&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  通过打开 PR 直接参与贡献&lt;/li&gt;
&lt;li&gt;  像任何开源项目中一样，你可以开始一个问题讨论&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;如果您想正式表示对项目的支持，您可以以&lt;a href="https://forms.gle/XVdT3JGUbLZQEHXu6"&gt;个人&lt;/a&gt;或&lt;a href="https://forms.gle/yifokDd3rfdFRG7i8"&gt;组织&lt;/a&gt;的身份申请成为 EMC 支持者。&lt;/p&gt;

&lt;p&gt;如果您想更多地参与 EMC 项目和组织的发展，您可以&lt;a href="https://forms.gle/XVdT3JGUbLZQEHXu6"&gt;个人&lt;/a&gt;或&lt;a href="https://forms.gle/yifokDd3rfdFRG7i8"&gt;组织&lt;/a&gt;的身份申请成为 EMC 成员。 &lt;/p&gt;

&lt;p&gt;如果您代表一个组织机构并且想要赞助 EMC，&lt;a href="https://forms.gle/yifokDd3rfdFRG7i8"&gt;请与我们联系&lt;/a&gt;。&lt;/p&gt;

&lt;p&gt;EMC 管理员&lt;br&gt;
马克·罗宾斯、侯赛因·阿尔·哈马德、爱丽丝·李&lt;/p&gt;

</description>
      <category>html</category>
      <category>标准</category>
      <category>电子邮件</category>
      <category>email</category>
    </item>
    <item>
      <title>Introducing the Email Markup Consortium (EMC)</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Wed, 25 May 2022 08:06:19 +0000</pubDate>
      <link>https://dev.to/emailmarkup/introducing-the-email-markup-consortium-emc-52ak</link>
      <guid>https://dev.to/emailmarkup/introducing-the-email-markup-consortium-emc-52ak</guid>
      <description>&lt;h2&gt;
  
  
  What is the Email Markup Consortium?
&lt;/h2&gt;

&lt;p&gt;The Email Markup Consortium (EMC) is a community-led group of industry professionals working to improve the email experience for everyone.&lt;/p&gt;

&lt;p&gt;Senders, recipients, and email clients share the common goals of improving user experience, accessibility, performance, consistency, and reliability. However, currently there is a lack of cooperation in trying to achieve these goals leading to inconsistent results. &lt;/p&gt;

&lt;p&gt;Recipients should be able to easily access the content of every email sent to them, regardless of their device, email client, assistive technology or internet speed. The EMC collaborates with developers, creation and sending tools, and email clients to drive this vision forward at every step of the email journey.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this needed?
&lt;/h2&gt;

&lt;p&gt;As stated above, there is a lack of cooperation between the relevant parties to work towards these shared goals.&lt;/p&gt;

&lt;p&gt;EMC is not the first project to attempt to address this. There have been several efforts in the past including:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://www.w3.org/2007/05/html-mail/html-email-standards"&gt;The Email Standards Project&lt;/a&gt; 2007&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://lists.w3.org/Archives/Public/public-html-mail/2007Feb/"&gt;W3C public-html-mail mailing list&lt;/a&gt; 2007&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://web.archive.org/web/2014*/Fixoutlook.org"&gt;Fix Outlook&lt;/a&gt;  2009&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.w3.org/community/htmail/"&gt;W3 HTML for Email Community Group&lt;/a&gt; 2014&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://www.litmus.com/blog/litmus-microsoft-partnership-update-2017/"&gt;Litmus Microsoft partnership&lt;/a&gt; 2016&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This highlights to us that there is indeed a gap and an on-going need for a project like EMC to help bring the relevant parties together and collaboratively work with them.&lt;/p&gt;

&lt;h2&gt;
  
  
  Why is this different to previous projects?
&lt;/h2&gt;

&lt;p&gt;Previous projects gained good support and helped move things forward. However, most of them have now been shut down or just left mostly unused.   &lt;/p&gt;

&lt;h3&gt;
  
  
  Longevity
&lt;/h3&gt;

&lt;p&gt;One of the goals of the EMC is longevity. We are structuring the EMC so that when the current members have moved on, the project will still live and be supported. To achieve this, we’re making the project as open as possible. Everything is posted publicly on GitHub where anyone can contribute.&lt;/p&gt;

&lt;p&gt;We’re also thinking about long term solutions for the continuing challenges of email markup as well as new challenges that may arise with new technology.  We’re not looking to only fix a few bugs. Instead, we’re looking to develop standards and maintain those standards moving forward.&lt;/p&gt;

&lt;h3&gt;
  
  
  Timing
&lt;/h3&gt;

&lt;p&gt;We think the timing of this project is better in comparison to previous attempts. In recent years the email community has grown massively and collaboration has hugely increased. There are new projects coming up all the time, built by the community for the community, such as the huge &lt;a href="https://email.geeks.chat/"&gt;EmailGeeks Slack group&lt;/a&gt;, &lt;a href="https://womenofemail.org/"&gt;Women of email&lt;/a&gt;, &lt;a href="https://www.caniemail.com/"&gt;CanIEmail&lt;/a&gt;, &lt;a href="https://howtotarget.email/"&gt;How to Target Email Clients&lt;/a&gt;, and many more. &lt;/p&gt;

&lt;h3&gt;
  
  
  Evidence of productive collaboration
&lt;/h3&gt;

&lt;p&gt;Seeing email clients collaboratively work on projects such as &lt;a href="https://amp.dev/about/email/"&gt;AMP for Email&lt;/a&gt; and adopting standards like &lt;a href="https://bimigroup.org/"&gt;BIMI&lt;/a&gt; shows us that different competing vendors in the email space can indeed work together.&lt;/p&gt;

&lt;h2&gt;
  
  
  How can people get involved?
&lt;/h2&gt;

&lt;p&gt;The project is open source and you can find us on &lt;a href="https://github.com/email-markup-consortium"&gt;GitHub&lt;/a&gt; where anyone can contribute:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;You can &lt;a href="https://github.com/email-markup-consortium/email-markup-consortium/discussions"&gt;start or join an existing discussion&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Contribute directly by opening a PR&lt;/li&gt;
&lt;li&gt;Open an issue like you would on any open source project&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you would like to publicly show your support for the project, you can apply to become an EMC supporter as an &lt;a href="https://forms.gle/XVdT3JGUbLZQEHXu6"&gt;individual&lt;/a&gt; or an &lt;a href="https://forms.gle/yifokDd3rfdFRG7i8"&gt;organisation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you would like to be more involved in EMC projects and the organisation’s direction, you can apply to become an EMC member as an &lt;a href="https://forms.gle/XVdT3JGUbLZQEHXu6"&gt;individual&lt;/a&gt; or an &lt;a href="https://forms.gle/yifokDd3rfdFRG7i8"&gt;organisation&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If you represent an organisation and you would like to sponsor EMC, please &lt;a href="https://forms.gle/yifokDd3rfdFRG7i8"&gt;get in touch&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;EMC Administrators&lt;br&gt;
Mark Robbins, Hussein Al Hammad, Alice Li&lt;/p&gt;

</description>
      <category>html</category>
      <category>standards</category>
      <category>email</category>
    </item>
    <item>
      <title>The privacy concerns of the noscript land</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Sat, 27 Feb 2021 09:21:30 +0000</pubDate>
      <link>https://dev.to/hus_hmd/the-privacy-concerns-of-the-noscript-land-5cid</link>
      <guid>https://dev.to/hus_hmd/the-privacy-concerns-of-the-noscript-land-5cid</guid>
      <description>&lt;p&gt;I have recently learned that deferred loading of &lt;code&gt;&amp;lt;img&amp;gt;&lt;/code&gt;s with the &lt;code&gt;loading&lt;/code&gt; attribute only works if JavaScript is enabled.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;loading=&lt;/span&gt;&lt;span class="s"&gt;"lazy"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/image.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#attr-loading"&gt;MDN documentation&lt;/a&gt; notes that this is an anti-tracking measure:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Loading is only deferred when JavaScript is enabled. This is an anti-tracking measure, because if a user agent supported lazy loading when scripting is disabled, it would still be possible for a site to track a user's approximate scroll position throughout a session, by strategically placing images in a page's markup such that a server can track how many images are requested and when.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;While the purpose of this behaviour seems reasonable on the surface, it made me thinks about two things:&lt;/p&gt;

&lt;h2&gt;
  
  
  1. The goal of disabling JS
&lt;/h2&gt;

&lt;p&gt;This anti-tracking measure assumes that a user's goal of disabling JS is to prevent websites from tracking them and their actions on pages. This assumption justifies loading more resources on the user's device even if they do not scroll far enough down a page to need them.&lt;/p&gt;

&lt;p&gt;I can't personally speak of the intention of disabling JS, but I am unsure how I feel about disabling the feature when JS is disabled in order to prevent tracking. After all, web features get maliciously used all the time.&lt;/p&gt;

&lt;p&gt;Disabling deferred loading on &lt;code&gt;img[loading=lazy]&lt;/code&gt; can have a direct impact on the user. I can see a user disabling JS in the browser to save on mobile data while browsing. They may not need to scroll all the way down to all pages. That is; they may not need to download all the images on all pages they visit. In this case, the anti-tracking measure backfires.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. The noscript tracking paths
&lt;/h2&gt;

&lt;p&gt;There are plenty of user-behaviour tracking approaches that work without JS. &lt;/p&gt;

&lt;h3&gt;
  
  
  The loading attribute on iframe
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;loading&lt;/code&gt; attribute also works on &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt;s. The current implementation of the &lt;code&gt;loading&lt;/code&gt; attribute on &lt;code&gt;&amp;lt;iframe&amp;gt;&lt;/code&gt; works even when JS is disabled. iFrame tracking pixels can be used to workaround the anti-tracking measure on images.&lt;/p&gt;

&lt;h3&gt;
  
  
  The ping attribute on anchor tags
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;ping&lt;/code&gt; attribute on an anchor tag is typically used for tracking. It accepts a space-separated list of URLs to which the browser sends POST requests when the link is followed:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;a&lt;/span&gt;
  &lt;span class="na"&gt;href=&lt;/span&gt;&lt;span class="s"&gt;"/contact"&lt;/span&gt;
  &lt;span class="na"&gt;ping=&lt;/span&gt;&lt;span class="s"&gt;"https://example.com/my-tracker https://example.com/my-other-tracker"&lt;/span&gt;
&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  Contact Us
&lt;span class="nt"&gt;&amp;lt;/a&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;ping&lt;/code&gt; attribute works even when JS is disabled. It is &lt;a href="https://caniuse.com/ping"&gt;disabled by default in Firefox&lt;/a&gt; though.&lt;/p&gt;

&lt;h3&gt;
  
  
  The noscript tag
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt; element can be used to conditionally load different/additional tracking pixels when JS is disabled:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;noscript&amp;gt;&lt;/span&gt;
  &lt;span class="c"&gt;&amp;lt;!-- add tracking pixels here --&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/noscript&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  The CSS approach
&lt;/h3&gt;

&lt;p&gt;CSS provides a number of ways to conditionally apply styles. It also provides a number of ways to load external resources such as images. So it is entirely possible to make use of this to track users without the need of JS.&lt;/p&gt;

&lt;p&gt;Using media queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;prefers-color-scheme&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;dark&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;#tracker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(/my-tracker.png)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Using feature queries and browser-specific prefixed CSS properties:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="k"&gt;@supports&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;-webkit-overflow-scrolling&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;touch&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;#tracker&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="sx"&gt;url(/my-tracker.png)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;CSS also provides a number of ways to apply styles based on user interactions. For example, you can track some user actions in a similar manner to the above using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes"&gt;pseudo-classes&lt;/a&gt;. And I'm sure there are more novel ways to make use of other CSS features for tracking.&lt;/p&gt;

&lt;h2&gt;
  
  
  Final thoughts
&lt;/h2&gt;

&lt;p&gt;Built-in anti-tracking measures is a very nice goal in theory, but it seems very hard to implement without sacrificing something else in return. &lt;/p&gt;

&lt;p&gt;So this begs the question: is "whether JS is enabled in the browser" the right criterion for enforcing built-in anti-tracking measures?&lt;/p&gt;




&lt;p&gt;This article was first published on &lt;a href="https://hussein-alhammad.com/blog/2021/02/privacy-concerns-of-noscript-land/"&gt;hussein-alhammad.com&lt;/a&gt; on 20 February 2021&lt;/p&gt;

</description>
      <category>privacy</category>
      <category>web</category>
    </item>
    <item>
      <title>Internationalised Domain Names</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Fri, 18 Dec 2020 09:27:45 +0000</pubDate>
      <link>https://dev.to/hus_hmd/internationalised-domain-names-3g66</link>
      <guid>https://dev.to/hus_hmd/internationalised-domain-names-3g66</guid>
      <description>&lt;p&gt;I have recently launched a new website (&lt;a href="https://%D9%88%D8%AC%D8%AF.%D9%85%D9%88%D9%82%D8%B9"&gt;wajad.art&lt;/a&gt;) with an &lt;a href="https://en.wikipedia.org/wiki/Internationalized_domain_name"&gt;internationalised domain name (IDN)&lt;/a&gt;. The domain name and all the page paths are in Arabic, which makes things more fun given Arabic is written right to left (RTL).&lt;/p&gt;

&lt;p&gt;Domain name is &lt;code&gt;وجد.موقع&lt;/code&gt;, and &lt;code&gt;موقع&lt;/code&gt; is the top-level domain (TLD), which is the equivalent to the &lt;code&gt;site&lt;/code&gt; TLD.&lt;/p&gt;

&lt;p&gt;A full URL example of page:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;وجد.موقع/م/أساطير-خليجية
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  How do IDNs work?
&lt;/h2&gt;

&lt;p&gt;Given the Domain Name System (DNS) has to use ASCII characters, they store IDNs as ASCII strings using &lt;a href="https://en.wikipedia.org/wiki/Punycode"&gt;Punycode&lt;/a&gt;, which is:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;a representation of Unicode with the limited ASCII character subset used for Internet hostnames&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So while my newly launched website's domain name is &lt;code&gt;وجد.موقع&lt;/code&gt;, in the DNS it is stored in the Punycode equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;xn--rgbg7e.xn--4gbrim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Fortunately, there are Punycode converters such as:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.punycoder.com/"&gt;punycoder.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.punycode.io/"&gt;punycode.io&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Domain Name vs Page Path
&lt;/h2&gt;

&lt;p&gt;The IDNs use Punycode to work around the DNS limitation of only supporting ASCII characters. This does not apply to the rest of the URL. You can use Unicode characters in the page path.&lt;/p&gt;

&lt;p&gt;MDN's &lt;a href="https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_URL"&gt;What is a URL?&lt;/a&gt; is a good resource to learn the different parts of a URL.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browsers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Unicode vs Punycode (ASCII)
&lt;/h3&gt;

&lt;p&gt;When navigating to a website with an IDN via the browser address bar, both the Unicode (e.g. &lt;code&gt;وجد.موقع&lt;/code&gt;) and the Punycode (e.g. &lt;code&gt;xn--rgbg7e.xn--4gbrim&lt;/code&gt;) work. &lt;/p&gt;

&lt;p&gt;Even if you typed in the Punycode in the address bar, web browsers may automatically convert the URL to the (human-friendly) Unicode equivalent if the URL meets the browser's IDN policy:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://chromium.googlesource.com/chromium/src/+/master/docs/idn.md"&gt;Google Chrome's IDN policy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://wiki.mozilla.org/IDN_Display_Algorithm"&gt;Firefox's IDN Display Algorithm&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The goal of these policies is to protect users from &lt;a href="https://en.wikipedia.org/wiki/IDN_homograph_attack"&gt;IDN homograph attack&lt;/a&gt;. There are also browser extensions that alerts users if they are on a site that uses Punycode in its domain name.&lt;/p&gt;

&lt;p&gt;Early this year, Google Chrome Developers YouTube channel's show HTTP 203 released an episode titled &lt;a href="https://www.youtube.com/watch?v=0-wB1VY3Nrc&amp;amp;t=1130"&gt;Humans can't read URLs. How can we fix it?&lt;/a&gt;. Jake and Surma briefly discuss how Chrome analyses the URL and when it may choose to display the Punycode over the Unicode.&lt;/p&gt;

&lt;h3&gt;
  
  
  RTL vs LTR
&lt;/h3&gt;

&lt;p&gt;If you ever mixed RTL and LTR languages when typing something on a digital device, you'd certainly have experienced frustrating times attempting to get words to flow correctly. The browser address bar doesn't handle this too well either.&lt;/p&gt;

&lt;p&gt;In the case of &lt;code&gt;وجد.موقع&lt;/code&gt;, it is read RTL. However, adding the &lt;code&gt;http&lt;/code&gt; protocol at the start means the address starts LTR. So you end up with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://وجد.موقع
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Even if you set the language in the browser to Arabic, which converts the UI to RTL:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/edge-rtl.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8gQ1zmR1--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/edge-rtl.png" alt="Microsoft Edge address bar" title="Microsoft Edge"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This is not a huge pain point, but it does look odd. As a developer I know the start is &lt;code&gt;https://&lt;/code&gt;. However, to an Arabic speaker who is not familiar with the protocol and its uses, they may interpret this as the URL ends in &lt;code&gt;https://&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This may be slightly off-topic, but it is worth noting that things become even more confusing if you use an ASCII domain name (LTR) with an RTL page path and vice versa:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;وجد.موقع/path/to/page

xn--rgbg7e.xn--4gbrim/الصفحة-1/الصفحة-2
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Copying the URL
&lt;/h3&gt;

&lt;p&gt;When you are on a website with an IDN and copy the URL directly from the address bar, what gets copied into your clipboard varies across browsers. &lt;/p&gt;

&lt;p&gt;Firefox (83.0) copies the Unicode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://وجد.موقع
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Chrome's (87.0.4280.66) behaviour is more sophisticated. If you include the &lt;code&gt;https&lt;/code&gt; protocol when you copy the URL from the address bar, it copies the Punycode into your clipboard:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://xn--rgbg7e.xn--4gbrim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you exclude the &lt;code&gt;https&lt;/code&gt; protocol, it copies the Unicode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;وجد.موقع
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The above behaviour only applies to the domain name. When it comes to the page path, the behaviour is also inconsistent across browsers. &lt;/p&gt;

&lt;p&gt;Firefox (83.0) encodes the page path to its UTF-8 representation when the URL is copied (think JavaScript's &lt;code&gt;encodeURI()&lt;/code&gt;, or PHP's &lt;code&gt;urlencode()&lt;/code&gt;), which is a huge UX pain for me in general and not only with IDNs. Receiving a URL in a chat app that fills up half my phone's screen with &lt;code&gt;%&lt;/code&gt;s and a mix of meaningless digits and English characters is pointless to me as a user.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://وجد.موقع/%D9%85/%D8%A3%D8%B3%D8%A7%D8%B7%D9%8A%D8%B1-%D8%AE%D9%84%D9%8A%D8%AC%D9%8A%D8%A9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;On Chrome (87.0.4280.66), if the &lt;code&gt;https&lt;/code&gt; protocol is included, it copies the Punycode domain name and the encoded page path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://xn--rgbg7e.xn--4gbrim/%D9%85/%D8%A3%D8%B3%D8%A7%D8%B7%D9%8A%D8%B1-%D8%AE%D9%84%D9%8A%D8%AC%D9%8A%D8%A9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the &lt;code&gt;https&lt;/code&gt; protocol is excluded, it copies the whole URL in Unicode:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;وجد.موقع/م/أساطير-خليجية
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sharing the URL
&lt;/h3&gt;

&lt;p&gt;Web browsers on smartphones and tablets offer a built-in sharing option, which gives you the choice to copy the URL or share directly to native apps. The behaviour across browsers here is also inconsistent. &lt;/p&gt;

&lt;p&gt;The same browser may not behave consistently when copying the URL from the address vs when copying/sharing the URL using the built-in share option. Samsung Internet (13.0.1.64), for instance, copies the Unicode (domain and page path) if you copy the URL directly from the address bar:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://وجد.موقع/م/أساطير-خليجية
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, it copies the Punycode and the encoded page path when using the built-in share option:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://xn--rgbg7e.xn--4gbrim/%D9%85/%D8%A3%D8%B3%D8%A7%D8%B7%D9%8A%D8%B1-%D8%AE%D9%84%D9%8A%D8%AC%D9%8A%D8%A9
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  JavaScript
&lt;/h2&gt;

&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Location"&gt;Location API&lt;/a&gt; returns the domain name in Punycode and encodes page paths:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"ancestorOrigins"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{},&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"href"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://xn--rgbg7e.xn--4gbrim/%D9%85/%D8%A3%D8%B3%D8%A7%D8%B7%D9%8A%D8%B1-%D8%AE%D9%84%D9%8A%D8%AC%D9%8A%D8%A9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"origin"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://xn--rgbg7e.xn--4gbrim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"protocol"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https:"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"host"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"xn--rgbg7e.xn--4gbrim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hostname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"xn--rgbg7e.xn--4gbrim"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"port"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"pathname"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/%D9%85/%D8%A3%D8%B3%D8%A7%D8%B7%D9%8A%D8%B1-%D8%AE%D9%84%D9%8A%D8%AC%D9%8A%D8%A9"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"search"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"hash"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;""&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The wilderness
&lt;/h2&gt;

&lt;p&gt;I have used a number of services in which I had to enter the IDN for Wajad or on which the domain name is displayed.&lt;/p&gt;

&lt;h3&gt;
  
  
  Domain registration
&lt;/h3&gt;

&lt;p&gt;Registering a domain with Punycode with a common TLD like &lt;code&gt;.com&lt;/code&gt; is not an obstacle. Some domain registrars allow you to use Unicode when searching domains e.g. &lt;code&gt;وجد.com&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;But I was looking for the internationalised TLD &lt;code&gt;موقع&lt;/code&gt;. It was not easy finding a domain registrar that sold &lt;code&gt;موقع&lt;/code&gt; domains. I ended up on multiple scammy-looking sites during my search. Eventually I bought the domain via &lt;a href="https://www.marcaria.com/"&gt;maracaria.com&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloudflare
&lt;/h3&gt;

&lt;p&gt;I had no issues adding IDNs with Unicode when adding the site to &lt;a href="https://www.cloudflare.com/"&gt;Cloudflare&lt;/a&gt;. They are also displayed in Unicode in the dashboard:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/cloudflare.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ixECbNoa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/cloudflare.png" alt="Cloudflare dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;However, Cloudflare used the Punycode in the email notifications they sent to me so far:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/cloudflare-email.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--xOoVig_S--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/cloudflare-email.png" alt="Cloudflare email notification"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Netlify
&lt;/h3&gt;

&lt;p&gt;Before launching the site, I set up a "coming soon" landing page on &lt;a href="https://www.netlify.com/"&gt;Netlify&lt;/a&gt;. Unlike Cloudflare, Netlify did not allow me to add the domain name with Unicode, and I had to enter the Punycode equivalent. Netlify's dashboard displays the domain in Punycode:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/netlify.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--UOWpYe2Q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/netlify.png" alt="Netlify dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Their email notifications also display the domain in Punycode:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/netlify-email.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--2xgaglg7--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/netlify-email.png" alt="Netlify email notification"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Cloudways
&lt;/h3&gt;

&lt;p&gt;Wajad's current PHP-based site is hosted on DigitalOcean via &lt;a href="https://www.cloudways.com/"&gt;Cloudways&lt;/a&gt;. The experience on Cloudways is similar to Netlify and I had to enter the Punycode:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/cloudways.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--952wu72I--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/cloudways.png" alt="Cloudways dashboard"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Search Console
&lt;/h3&gt;

&lt;p&gt;I was able to add the site to Google Search Console with the Unicode version of the domain. Oddly, some subsequent forms did not accept Unicode:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/search-console-sitemap-form.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--P6u-do-N--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/search-console-sitemap-form.png" alt="Google Search Console sitemap form"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;So I had to enter the Punycode equivalent, but Google Search Console displayed the URL in Unicode after submitting the form:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/search-console-sitemap-list.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--RlAnxCXc--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/search-console-sitemap-list.png" alt="Google Search Console sitemap form"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fortunately, email notifications use Unicode:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/search-console-email.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--i3oBzmIt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/search-console-email.png" alt="Google Search Console sitemap form"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Google Search results
&lt;/h3&gt;

&lt;p&gt;Google Search results display the domain name in Unicode. I already knew it displayed Arabic correctly for breadcrumbs, but it is really nice to see the domain name displayed in a human-friendly manner:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/google-search.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k95OoEmt--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/google-search.png" alt="Google search result - IDN"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Both Unicode and Punycode are supported when using &lt;a href="https://support.google.com/websearch/answer/2466433"&gt;search operators&lt;/a&gt; like &lt;code&gt;site:&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;site:وجد.موقع

site:xn--rgbg7e.xn--4gbrim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Bing Webmaster Tools
&lt;/h3&gt;

&lt;p&gt;Bing Webmaster Tools allow you to import verified sites from Google Search Console. Upon an import attempt it displayed an error message saying the site addition was unsuccessful:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/bing-import.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--cd4t0QaI--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/bing-import.png" alt="Bing Webmaster Tools - import error message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I attempted to enter the URL manually as suggested, but the Unicode was not accepted:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/bing-import-2.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--8xQn6MEz--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/bing-import-2.png" alt="Bing Webmaster Tools - import error message"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Then when I went to check the list of sites under my account, Wajad was actually listed! I'm not entirely sure which of the above attempts was the successful one.&lt;/p&gt;

&lt;p&gt;Bing Webmaster Tools lists the domain in Unicode, but when you open the dashboard for the site it lists the Punycode:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/bing-sites-list.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--6hgyPUZ4--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/bing-sites-list.png" alt="Bing Webmaster Tools - sites list"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I had the opposite experience to Google Search Console when submitting the sitemap. The form accepted the Unicode, but the sitemap list displays the Punycode:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/bing-sitemap-form.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TumO5o-e--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/bing-sitemap-form.png" alt="Bing Webmaster Tools - sitemap form"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://hussein-alhammad.com/assets/images/idn/bing-sitemap-list.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--TxW8CQ_p--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/bing-sitemap-list.png" alt="Bing Webmaster Tools - sitemap list"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Bing search results
&lt;/h3&gt;

&lt;p&gt;I have only recently submitted the sitemap via Bing Webmaster Tools, so I still do not know the full picture. From what I can tell so far Bing search results also display the domain in Unicode. &lt;/p&gt;

&lt;p&gt;However, it seems only Punycode is supported when using &lt;a href="https://docs.microsoft.com/en-us/previous-versions/bing/search/ff795620(v=msdn.10)"&gt;search operators&lt;/a&gt; like &lt;code&gt;site:&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;site:xn--rgbg7e.xn--4gbrim
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/bing-search.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s---8b_t0Ky--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/bing-search.png" alt="Bing search result - IDN"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Fathom Analytics
&lt;/h3&gt;

&lt;p&gt;I had no issue using the Unicode version of the domain when adding the site to &lt;a href="https://usefathom.com/"&gt;Fathom Analytics&lt;/a&gt;. The domain is always displayed in Unicode (dashboard and email notifications).&lt;/p&gt;

&lt;p&gt;Their recently-launched tool &lt;a href="https://usephantom.com/"&gt;Phantom Analyzer&lt;/a&gt; also allowed me to enter the URL in Unicode, but the results page displayed the domain in Punycode.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/phantom-analyzer.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--bFFibXXa--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/phantom-analyzer.png" alt="Phantom Analyzer results"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Zoho Mail
&lt;/h3&gt;

&lt;p&gt;Neither Unicode nor Punycode is supported when signing up to &lt;a href="https://www.zoho.com/mail/"&gt;Zoho Mail&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/zoho-mail.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--BAq8jc0_--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/zoho-mail.png" alt="Zoho Mail - Unicode sign up"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://hussein-alhammad.com/assets/images/idn/zoho-mail-punycode.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--c-BjVLXf--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/zoho-mail-punycode.png" alt="Zoho Mail - Punycode sign up"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Emails
&lt;/h3&gt;

&lt;p&gt;G Suite (now Google Workspace) allowed me to sign up with my IDN. I sent test emails to Gmail, Yahoo and Outlook. Gmail was the only one to display the domain name in Unicode. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://hussein-alhammad.com/assets/images/idn/gmail.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--etn-lMtd--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/gmail.png" alt="Gmail - received email from IDN with Punycode"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://hussein-alhammad.com/assets/images/idn/outlook.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--qKW1BQg0--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/outlook.png" alt="Outlook - received email from IDN with Punycode"&gt;&lt;/a&gt;&lt;br&gt;
&lt;a href="https://hussein-alhammad.com/assets/images/idn/yahoo.png"&gt;&lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fEeT_pst--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://hussein-alhammad.com/assets/images/idn/yahoo.png" alt="Yahoo - received email from IDN with Punycode"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I have also sent HTML email tests with images. Yahoo Mail and Windows Mail did not load images whose &lt;code&gt;src&lt;/code&gt; had the domain in Unicode, but Gmail did:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;img&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"https://وجد.موقع/path/to/image.jpg"&lt;/span&gt; &lt;span class="na"&gt;alt=&lt;/span&gt;&lt;span class="s"&gt;""&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Auto-linking
&lt;/h3&gt;

&lt;p&gt;When sending messages via chat apps, adding the &lt;code&gt;https&lt;/code&gt; protocol to the URL (with domain name in Unicode) seems to be enough for most apps.&lt;/p&gt;

&lt;p&gt;Although email clients are known for linking text in HTML emails when you don't want them to, I found Gmail and Windows Mail don't auto-link:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;https://وجد.موقع
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  In-app browsers
&lt;/h3&gt;

&lt;p&gt;The behaviour of in-app browsers is consistent. On iOS, Instagram's in-app browser displays the domain in Punycode, while Twitter's in-app browser displays the domain in Unicode.&lt;/p&gt;

&lt;h2&gt;
  
  
  I understand, but..
&lt;/h2&gt;

&lt;p&gt;I understand why I'm seeing very different behaviour across browsers and apps, but as a developer and a user I just would love to see a better user experience overall.&lt;/p&gt;

&lt;p&gt;Wajad is still a young side project, but it is clear to me that I'll run into more interesting IDN-related scenarios as it grows and I'll try my best to document them.&lt;/p&gt;




&lt;p&gt;This article was first published on &lt;a href="https://hussein-alhammad.com/blog/2020/12/internationalised-domain-names/"&gt;hussein-alhammad.com&lt;/a&gt;&lt;/p&gt;

</description>
      <category>domains</category>
      <category>idn</category>
      <category>arabic</category>
    </item>
    <item>
      <title>RTL support lands in Bootrstrap and Bulma</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Sat, 18 Jul 2020 14:01:20 +0000</pubDate>
      <link>https://dev.to/hus_hmd/rtl-support-lands-in-bootrstrap-and-bulma-3hom</link>
      <guid>https://dev.to/hus_hmd/rtl-support-lands-in-bootrstrap-and-bulma-3hom</guid>
      <description>&lt;p&gt;On 7 June 2020 &lt;a href="https://bulma.io/"&gt;Bulma&lt;/a&gt; &lt;a href="https://github.com/jgthms/bulma/releases/tag/0.9.0"&gt;v0.9.0&lt;/a&gt; was released and while I always wanted the spacing helpers it introduced, what I was most excited about is the RTL support!&lt;/p&gt;

&lt;p&gt;Shortly after, &lt;a href="https://blog.getbootstrap.com/2020/06/16/bootstrap-5-alpha/"&gt;Bootstrap 5 alpha&lt;/a&gt; was released and they also announced RTL support!&lt;/p&gt;

&lt;p&gt;I live in a part of the world where it is becoming extremely common for websites and web apps to offer both English (LTR) and Arabic (RTL) versions. Seeing popular CSS frameworks add built-in support for RTL is a huge plus for many developers in this region, and I certainly hope more open-source projects follow suit.&lt;/p&gt;

&lt;p&gt;Having said that, I do realise my role in this and I feel developers (including me) who want to see RTL support in more open-source projects should be contributing to such projects (if they have the required skill set); particularly if it is a small project with a single or very few maintainers.&lt;/p&gt;

</description>
      <category>css</category>
      <category>rtl</category>
    </item>
    <item>
      <title>Alpine.js: responsive x-cloak</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Fri, 03 Apr 2020 12:59:30 +0000</pubDate>
      <link>https://dev.to/hus_hmd/alpine-js-responsive-x-cloak-3blp</link>
      <guid>https://dev.to/hus_hmd/alpine-js-responsive-x-cloak-3blp</guid>
      <description>&lt;p&gt;When using &lt;a href="https://github.com/alpinejs/alpine"&gt;Alpine.js&lt;/a&gt; the &lt;code&gt;x-cloak&lt;/code&gt; attribute is removed from DOM elements when Alpine is initialised. As noted in the docs, this makes it useful for hiding elements until Alpine is initialised:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;x-cloak&lt;/code&gt; attributes are removed from elements when Alpine initializes. This is useful for hiding pre-initialized DOM. It's typical to add the following global style for this to work: &lt;/p&gt;


&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;x-cloak&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="o"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="nt"&gt;style&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/blockquote&gt;

&lt;p&gt;You may want to hide pre-initialised DOM on some screen sizes, but not others. A good example for this is the links in a site's navigation bar, which are typically hidden by default on smaller screen sizes, but are always visible on wider screens. &lt;/p&gt;

&lt;p&gt;So instead of hiding all elements with the &lt;code&gt;x-cloak&lt;/code&gt; attribute, we can hide only the ones whose &lt;code&gt;x-cloak&lt;/code&gt; attribute has no value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;x-cloak&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;""&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to target elements whose &lt;code&gt;x-cloak&lt;/code&gt; attribute has a value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;x-cloak&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"some-value"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So now we can write CSS rules targeting elements whose &lt;code&gt;x-cloak&lt;/code&gt; value is &lt;code&gt;mobile&lt;/code&gt;, &lt;code&gt;tablet&lt;/code&gt;, &lt;code&gt;desktop&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="c"&gt;/* always hidden */&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;x-cloak&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;""&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;/* hidden on mobile/smaller screens */&lt;/span&gt;
&lt;span class="k"&gt;@media&lt;/span&gt; &lt;span class="n"&gt;screen&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;max-width&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;768px&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;x-cloak&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"mobile"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nl"&gt;display&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;none&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



</description>
      <category>alpinejs</category>
      <category>css</category>
    </item>
    <item>
      <title>Bidirectional horizontal rules in CSS</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Tue, 22 Oct 2019 10:34:51 +0000</pubDate>
      <link>https://dev.to/hus_hmd/bidirectional-horizontal-rules-in-css-56f4</link>
      <guid>https://dev.to/hus_hmd/bidirectional-horizontal-rules-in-css-56f4</guid>
      <description>&lt;p&gt;The &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir"&gt;dir attribute in HTML&lt;/a&gt; and the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/direction"&gt;dir property in CSS&lt;/a&gt; can be used to set the direction of text and horizontal flow. Some languages are written Left-To-Right (LTR), while others are written Right-To-Left (RTL). So having this level of control is vital for creating documents and interfaces for the web.&lt;/p&gt;

&lt;p&gt;Building an interface to support both LTR and RTL layouts is a challenge. Flexbox and Grid certainly makes things easier, but they don't cover all our styling needs.&lt;/p&gt;

&lt;p&gt;There are many CSS rules we write in which we specify a physical direction or side. For instance, when we write CSS to layout horizontal elements, it is common to set a margin only on a single side and set a margin of &lt;code&gt;0&lt;/code&gt; (on the same side) to the first or last sibling element.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nc"&gt;.element&lt;/span&gt;&lt;span class="nd"&gt;:last-child&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

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

&lt;/div&gt;



&lt;p&gt;Or&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:last-child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;margin-right&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the above example we are adding a margin on the right side of each element except the last. That's how it is written. Though what we mean when we write this is to add a margin &lt;em&gt;after&lt;/em&gt; the element in the direction of the horizontal flow of the document (or the parent element).&lt;/p&gt;

&lt;p&gt;A common way to style &lt;code&gt;blockquote&lt;/code&gt; is to add a border to one side of the quote; the side we consider to come &lt;em&gt;before&lt;/em&gt; the quote.&lt;/p&gt;

&lt;p&gt;This is &lt;a href="https://bulma.io/"&gt;Bulma&lt;/a&gt;'s &lt;code&gt;&amp;lt;blockquote&amp;gt;&lt;/code&gt; styling:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.content&lt;/span&gt; &lt;span class="nt"&gt;blockquote&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nl"&gt;background-color&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;#f5f5f5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;border-left&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;5px&lt;/span&gt; &lt;span class="nb"&gt;solid&lt;/span&gt; &lt;span class="m"&gt;#dbdbdb&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nl"&gt;padding&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1.25em&lt;/span&gt; &lt;span class="m"&gt;1.5em&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And there are many other styling choices we make in which we specify a side/direction (left/right) in CSS, but what we actually mean is before/after.&lt;/p&gt;

&lt;p&gt;So when building interfaces that support both LTR and RTL layouts, one option would be to write CSS rules like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.class&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

&lt;span class="nt"&gt;html&lt;/span&gt;&lt;span class="o"&gt;[&lt;/span&gt;&lt;span class="nt"&gt;dir&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s1"&gt;"rtl"&lt;/span&gt;&lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="nc"&gt;.class&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or perhaps even load different stylesheets for LTR and RTL layouts. However, both options require we either write more CSS or &lt;a href="https://gist.github.com/Integralist/7269907"&gt;set up our tooling to generate the appropriate flipped styles&lt;/a&gt;. And there are also &lt;a href="https://rtl.daskhat.ir/"&gt;tools that convert LTR to RTL styles&lt;/a&gt; for you.&lt;/p&gt;

&lt;p&gt;Wouldn't it be nice to work with a lower level of abstraction instead? What if we can tell the browser we are targeting the side before/after an element instead of referring to the physical directions left/right? At the end of the day this is what we mean a lot of the times. This reminds me of this tweet: &lt;/p&gt;


&lt;blockquote class="ltag__twitter-tweet"&gt;

  &lt;div class="ltag__twitter-tweet__main"&gt;
    &lt;div class="ltag__twitter-tweet__header"&gt;
      &lt;img class="ltag__twitter-tweet__profile-image" src="https://res.cloudinary.com/practicaldev/image/fetch/s--CnTquL_q--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://pbs.twimg.com/profile_images/818626883432554497/uOwnZK4i_normal.jpg" alt="keith•j•grant profile image"&gt;
      &lt;div class="ltag__twitter-tweet__full-name"&gt;
        keith•j•grant
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__username"&gt;
        &lt;a class="mentioned-user" href="https://dev.to/keithjgrant"&gt;@keithjgrant&lt;/a&gt;
      &lt;/div&gt;
      &lt;div class="ltag__twitter-tweet__twitter-logo"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--ir1kO05j--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-f95605061196010f91e64806688390eb1a4dbc9e913682e043eb8b1e06ca484f.svg" alt="twitter logo"&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__body"&gt;
      When you code CSS, you’re writing abstract rules to take *unknown* content and organize it in an *unknown* medium. That shit is hard.
    &lt;/div&gt;
    &lt;div class="ltag__twitter-tweet__date"&gt;
      13:26 PM - 17 Mar 2017
    &lt;/div&gt;


    &lt;div class="ltag__twitter-tweet__actions"&gt;
      &lt;a href="https://twitter.com/intent/tweet?in_reply_to=842728744653676544" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--fFnoeFxk--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-reply-action-238fe0a37991706a6880ed13941c3efd6b371e4aefe288fe8e0db85250708bc4.svg" alt="Twitter reply action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/retweet?tweet_id=842728744653676544" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--k6dcrOn8--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-retweet-action-632c83532a4e7de573c5c08dbb090ee18b348b13e2793175fea914827bc42046.svg" alt="Twitter retweet action"&gt;
      &lt;/a&gt;
      &lt;a href="https://twitter.com/intent/like?tweet_id=842728744653676544" class="ltag__twitter-tweet__actions__button"&gt;
        &lt;img src="https://res.cloudinary.com/practicaldev/image/fetch/s--SRQc9lOp--/c_limit%2Cf_auto%2Cfl_progressive%2Cq_auto%2Cw_880/https://dev.to/assets/twitter-like-action-1ea89f4b87c7d37465b0eb78d51fcb7fe6c03a089805d7ea014ba71365be5171.svg" alt="Twitter like action"&gt;
      &lt;/a&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/blockquote&gt;


&lt;p&gt;CSS has what is called &lt;em&gt;logical properties&lt;/em&gt;. We can now tell the browser what we actually mean. Instead of using &lt;code&gt;-left&lt;/code&gt; and &lt;code&gt;-right&lt;/code&gt;, we can use &lt;code&gt;-inline-start&lt;/code&gt; and &lt;code&gt;-inline-end&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight css"&gt;&lt;code&gt;&lt;span class="nc"&gt;.element&lt;/span&gt;&lt;span class="nd"&gt;:not&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nd"&gt;:last-child&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="py"&gt;margin-inline-end&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1rem&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Similarly instead of using &lt;code&gt;-top&lt;/code&gt; and &lt;code&gt;-bottom&lt;/code&gt;, we can use &lt;code&gt;-block-start&lt;/code&gt; and &lt;code&gt;-block-end&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This means we can write one set of rules that target both LTR and RTL layouts. Here is an example using the &lt;code&gt;margin-inline-end&lt;/code&gt; property:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hus_hmd/embed/bGGgMZd?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Using the &lt;code&gt;border-inline-start&lt;/code&gt; and &lt;code&gt;padding-inline-start&lt;/code&gt; properties:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hus_hmd/embed/vYYgrBM?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;Firefox also supports &lt;code&gt;border-*-*-radius&lt;/code&gt; so you can target different corners with &lt;code&gt;border-start-start-radius&lt;/code&gt;, &lt;code&gt;border-end-start-radius&lt;/code&gt;, etc.&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hus_hmd/embed/abbpKzK?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;All demos:&lt;/p&gt;

&lt;p&gt;&lt;iframe height="600" src="https://codepen.io/hus_hmd/embed/YzzNzPp?height=600&amp;amp;default-tab=result&amp;amp;embed-version=2"&gt;
&lt;/iframe&gt;
&lt;/p&gt;

&lt;p&gt;For a deeper explanation, you can refer to Rachel Andrew's article &lt;a href="https://www.smashingmagazine.com/2018/03/understanding-logical-properties-values/"&gt;Understanding Logical Properties And Values&lt;/a&gt;. This is not just about RTL interfaces or horizontal bidirectional CSS rules. Rachel's article also covers logical dimensions.&lt;/p&gt;

&lt;h2&gt;
  
  
  Browser Support
&lt;/h2&gt;

&lt;p&gt;Can I Use?:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://caniuse.com/#feat=css-logical-props"&gt;Logical Properties&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://caniuse.com/#feat=mdn-css_properties_border-start-start-radius"&gt;border-*-*-radius&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>css</category>
      <category>rtl</category>
      <category>multilingual</category>
    </item>
    <item>
      <title>Every developer builds a CMS!</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Wed, 25 Sep 2019 11:03:00 +0000</pubDate>
      <link>https://dev.to/hus_hmd/every-developer-builds-a-cms-1n47</link>
      <guid>https://dev.to/hus_hmd/every-developer-builds-a-cms-1n47</guid>
      <description>&lt;p&gt;"Every developer eventually builds a CMS" is a joke I came across enough times that I promised myself I wouldn't do it. Although I think the joke often comes from developers who have been in the industry for a lot longer than I have, and perhaps enough of them either built or came across custom CMS solutions.&lt;/p&gt;

&lt;p&gt;Luckily, we are no longer in the era in which building a bespoke CMS is common for one-off projects. On the other hand, while there are many CMS products in the market we are very much in the era of using (or repurposing) SaaS applications as headless Content Management Systems. &lt;/p&gt;

&lt;p&gt;Many applications have nice interfaces, customisable data structures, native mobile apps and developer-friendly APIs. Some even have built-in field types! The ability to build custom extensions provided by some applications also open doors to fill in any gaps in order to utilise them as CMS solutions.&lt;/p&gt;

&lt;h2&gt;
  
  
  CMS has a competition
&lt;/h2&gt;

&lt;p&gt;Content has a new potential home. CMS products have competition from products that are not classified as a CMS or site builders and, in many cases, not built to solve the same problems. These products can perform many of the same tasks and some may even out-perform traditional CMS products in some aspects.&lt;/p&gt;

&lt;p&gt;The bar is a little higher for CMS products nowadays. The expected feature list is a bit longer ranging from built-in third-party integrations to real-time collaboration and from customisability to ease-of-use. &lt;/p&gt;

&lt;p&gt;The CMS target audience no longer compares a CMS product only against other CMS products, but also against other digital products. A Content Management System is a digital product after all. When users are exposed to a wider range of digital products and find a feature has become so common amongst these products, they may eventually expect the average CMS to support it too. &lt;/p&gt;

&lt;h2&gt;
  
  
  What can you use as a CMS?
&lt;/h2&gt;

&lt;p&gt;There are several products you can use as a CMS:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/max-barry/google-drive-cms"&gt;Google Drive&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://blog.usejournal.com/how-to-use-google-sheets-as-a-cms-or-a-database-f9d8e736fdce"&gt;Google Sheets&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://github.com/postlight/liftoff"&gt;Airtable&lt;/a&gt; / more &lt;a href="https://airtable.com/universe/exp6Y34FZJdv6mKS5/twilios-lightweight-cms"&gt;Airtable&lt;/a&gt; / &lt;a href="https://blog.airtable.com/build-your-own-custom-blog-cms-with-airtable-and-gatsbyjs/"&gt;Aritable + Gatsby&lt;/a&gt; / even CSS-Tricks has an article on using &lt;a href="https://css-tricks.com/getting-to-grips-with-the-airtable-api/"&gt;Airtable&lt;/a&gt; as a CMS&lt;/li&gt;
&lt;li&gt;&lt;a href="https://github.com/Troglio/troglio"&gt;Trello&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flyingsquirrelbook.com/notes/2/evernote-as-a-cms/"&gt;Evernote&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Zenkit, a SaaS product that offers a good deal of customisability, even suggests on &lt;a href="https://zenkit.com/en/use-cases/project-management/"&gt;their website&lt;/a&gt; that you can use the product as a CMS:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Don’t just manage projects – create a CRM, &lt;strong&gt;CMS&lt;/strong&gt;, ERP, or anything else you need.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And you probably can create your own custom headless CMS solution using &lt;a href="https://www.zoho.com/creator/"&gt;Zoho Creator&lt;/a&gt;, a low-code platform. &lt;/p&gt;

&lt;h2&gt;
  
  
  Not a one-size-fits-all
&lt;/h2&gt;

&lt;p&gt;As with almost everything in the tech world, using a digital product that isn't a CMS to manage and deliver content to websites does not suit all use cases. I'm not claiming that. However, this approach is certainly viable. &lt;/p&gt;

&lt;p&gt;We've seen site builders compete against CMS products and services such as Squarespace and Wix now serve a market that otherwise would rely on a CMS to power their websites. We've seen many developers ditch CMS solutions in favour for static site generators when possible. So I don't think it is too crazy to consider some SaaS products as alternatives to content management systems, especially when a product like Airtable can also be used for managing other aspects of a business (e.g. project management, CRM).&lt;/p&gt;

&lt;p&gt;I do, however, think the headless CMS scene has great options. So unless a company is already using a product for managing other aspects of the business, it probably makes more sense to pick a tool that was designed for managing and delivering content.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;If you were to use a SaaS product as a headless CMS, what product would you choose?&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>cms</category>
    </item>
    <item>
      <title>Favourite albums to listen to while coding</title>
      <dc:creator>Hussein Al Hammad</dc:creator>
      <pubDate>Sun, 18 Nov 2018 10:43:25 +0000</pubDate>
      <link>https://dev.to/hus_hmd/favourite-albums-to-listen-to-while-coding-25fb</link>
      <guid>https://dev.to/hus_hmd/favourite-albums-to-listen-to-while-coding-25fb</guid>
      <description>&lt;p&gt;Like many developers I often put my headphones on when coding. It helps me get in the zone, block out other distractions and get into that flow state.&lt;/p&gt;

&lt;p&gt;Not all types of music helps me though. I find what works for me best is listening to instrumental albums, particularly progressive rock/metal. The tracks feel structured and often flow nicely. &lt;/p&gt;

&lt;p&gt;And the flow is not just on a track-by-track basis. The whole album just flows and, as a result, so do my thoughts. So I don't play these on shuffle (who plays albums on shuffle?). I also occasionally play them at the gym too!&lt;/p&gt;

&lt;p&gt;Below is a list of my favourite instrumental albums to listen to while coding. And here's a &lt;a href="https://open.spotify.com/user/1284397941/playlist/4olgCu22Fb0Xje2JFerKdN?si=Os189sT0RP2ltMExF4-CIA" rel="noopener noreferrer"&gt;Spotify playlist&lt;/a&gt; containing them all.&lt;/p&gt;

&lt;h3&gt;
  
  
  1. &lt;a href="https://open.spotify.com/album/54LcH6rOpnX8afrvtGvL1h?si=_PrVbxhZSs6Gyvg30KeUxw" rel="noopener noreferrer"&gt;(II)&lt;/a&gt; by &lt;a href="https://open.spotify.com/artist/3cgIU3hh7Y4pUsPgHB8aYT?si=LY0FwRKnTUWkqbhXuzEjbg" rel="noopener noreferrer"&gt;Toundra&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  2. &lt;a href="https://open.spotify.com/album/3cWgv0dLq4Odj2iYnnhcqU?si=3bEvzkO2TR-2LvFU26DIEQ" rel="noopener noreferrer"&gt;Mozaic&lt;/a&gt; by &lt;a href="https://open.spotify.com/artist/09VgjC02elNRzXBG9Kc4R2?si=CHIXwt-VQCmpQEajLkFSrg" rel="noopener noreferrer"&gt;Sunset in the 12th House&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  3. &lt;a href="https://open.spotify.com/album/6tbMoRTY3brzgQfwSzkTGH?si=tXMRrPGkSrO6ns4jab1YMA" rel="noopener noreferrer"&gt;Back to Earth&lt;/a&gt; by &lt;a href="https://open.spotify.com/artist/7935eVYpj7jQM3mRJ3kGeX?si=M-tpkoQ4QQaFUHtsRr6gEQ" rel="noopener noreferrer"&gt;Exxasens&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  4. &lt;a href="https://open.spotify.com/album/6w7q5ueU8FNwqSYDgxaqqg?si=7PYC51aTQdG7yLPdB0Q8Hw" rel="noopener noreferrer"&gt;Boundless&lt;/a&gt; by &lt;a href="https://open.spotify.com/artist/3SiCxhceGZgzusCLHd4Zz6?si=e0GShmi9Q_OBZS4HXyrkjg" rel="noopener noreferrer"&gt;Long Distance Calling&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  5. &lt;a href="https://open.spotify.com/album/6Ued283OOMYn1KTaheTflx?si=kUiTTN6CRuGxLNU6hABkWA" rel="noopener noreferrer"&gt;(III)&lt;/a&gt; by &lt;a href="https://open.spotify.com/artist/3cgIU3hh7Y4pUsPgHB8aYT?si=LY0FwRKnTUWkqbhXuzEjbg" rel="noopener noreferrer"&gt;Toundra&lt;/a&gt;
&lt;/h3&gt;

&lt;h3&gt;
  
  
  6. &lt;a href="https://open.spotify.com/album/3OLFb9cgHkWklwjXqB6AbH?si=0pVYIkbfTf6Tj_fjHPyfeg" rel="noopener noreferrer"&gt;O&lt;/a&gt; by &lt;a href="https://open.spotify.com/artist/4vjUp8pCIGfJVuBOKddn3B?si=SRntv7scTUqjxP5SVtBAcw" rel="noopener noreferrer"&gt;The Gentle Art of Cooking People&lt;/a&gt;
&lt;/h3&gt;

</description>
      <category>music</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
