<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Web components | Nerdpress.org</title>
	<atom:link href="https://nerdpress.org/category/frontend-engineering/web-components/feed/" rel="self" type="application/rss+xml" />
	<link>https://nerdpress.org</link>
	<description>...dev, tech problems and solutions.</description>
	<lastBuildDate>Fri, 07 Feb 2025 09:39:15 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>
	<item>
		<title>ObfuscateLink Web Component in Astro</title>
		<link>https://nerdpress.org/2025/02/07/obfuscatelink-web-component-in-astro/</link>
		
		<dc:creator><![CDATA[Ivo Bathke]]></dc:creator>
		<pubDate>Fri, 07 Feb 2025 09:36:02 +0000</pubDate>
				<category><![CDATA[Astro]]></category>
		<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Web components]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=3393</guid>

					<description><![CDATA[<p>Using Web Components in Astro wasn&#8217;t as straightforward as expected. Here&#8217;s an example showing how to integrate the obfuscate-link web component into an Astro project.&#160; First, add the Obfuscate-Link web component to the project: Now register ObfuscateLink with customElements:&#160; This occurs in the Layout.astro component, making it available across all pages. The registration happens within &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2025/02/07/obfuscatelink-web-component-in-astro/" class="more-link">Continue reading<span class="screen-reader-text"> "ObfuscateLink Web Component in Astro"</span></a></p>
The post <a href="https://nerdpress.org/2025/02/07/obfuscatelink-web-component-in-astro/">ObfuscateLink Web Component in Astro</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Using Web Components in <a href="https://astro.build/" title="">Astro</a> wasn&#8217;t as straightforward as expected. Here&#8217;s an example showing how to integrate the <a href="https://github.com/ivoba/obfuscate-wc" title="">obfuscate-link</a> web component into an Astro project.&nbsp;</p>



<p>First, add the Obfuscate-Link web component to the project:</p>


<pre class="wp-block-code"><span><code class="hljs">npm install obfuscate-link-web-component</code></span></pre>


<span id="more-3393"></span>



<p>Now register ObfuscateLink with customElements:&nbsp;</p>


<pre class="wp-block-code"><span><code class="hljs language-xml"><span class="hljs-tag">&lt;<span class="hljs-name">body</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">slot</span> /&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">script</span>&gt;</span><span class="javascript">
      <span class="hljs-keyword">import</span> { ObfuscateLink } <span class="hljs-keyword">from</span> <span class="hljs-string">'obfuscate-link-web-component'</span>;
      <span class="hljs-comment">// Only define the custom element if it hasn't been defined yet</span>
      <span class="hljs-keyword">if</span> (!customElements.get(<span class="hljs-string">'obfuscate-link'</span>)) {
        customElements.define(<span class="hljs-string">'obfuscate-link'</span>, ObfuscateLink);
      }
    </span><span class="hljs-tag">&lt;/<span class="hljs-name">script</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">body</span>&gt;</span></code></span></pre>


<p>This occurs in the Layout.astro component, making it available across all pages. The registration happens within a script tag in the HTML to execute only on the client side, avoiding it execution while SSR rendering performed by Astro beforehand.</p>



<p>Next, create an Astro component that wraps the web-component and handles the obfuscation by encoding the passed prop.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">---
type BaseProps = {
  id?: string;
}
type EmailProps = BaseProps &amp; {
  <span class="hljs-attr">email</span>: string;
  tel?: never;
  sms?: never;
  facetime?: never;
  href?: never;
}
type TelProps = BaseProps &amp; {
  email?: never;
  tel: string;
  sms?: never;
  facetime?: never;
  href?: never;
}
type SmsProps = BaseProps &amp; {
  email?: never;
  tel?: never;
  sms: string;
  facetime?: never;
  href?: never;
}
type FacetimeProps = BaseProps &amp; {
  email?: never;
  tel?: never;
  sms?: never;
  facetime: string;
  href?: never;
}
type HrefProps = BaseProps &amp; {
  email?: never;
  tel?: never;
  sms?: never;
  facetime?: never;
  href: string;
}
<span class="hljs-keyword">export</span> type Props = EmailProps | TelProps | SmsProps | FacetimeProps | HrefProps;
<span class="hljs-keyword">const</span> props = Astro.props;
<span class="hljs-keyword">const</span> { id } = props;
<span class="hljs-comment">// Find the active prop (email, tel, sms, facetime, or href)</span>
<span class="hljs-keyword">const</span> activeProp = <span class="hljs-built_in">Object</span>.entries(props).find(<span class="hljs-function">(<span class="hljs-params">&#91;key, value]</span>) =&gt;</span> 
  key !== <span class="hljs-string">'id'</span> &amp;&amp; value !== <span class="hljs-literal">undefined</span>
);
<span class="hljs-keyword">let</span> attribute = <span class="hljs-string">''</span>;
<span class="hljs-keyword">let</span> value = <span class="hljs-string">''</span>;
<span class="hljs-keyword">if</span> (activeProp) {
  &#91;attribute, value] = activeProp;
  <span class="hljs-keyword">const</span> orgValue = value;
  value = Buffer.from(value).toString(<span class="hljs-string">'base64'</span>);
}
---

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">obfuscate-link</span>
  <span class="hljs-attr">id</span>=<span class="hljs-string">{id}</span>
  {<span class="hljs-attr">...</span>{&#91;<span class="hljs-attr">attribute</span>]<span class="hljs-attr">:</span> <span class="hljs-attr">value</span>}}
&gt;</span><span class="hljs-tag">&lt;<span class="hljs-name">slot</span> /&gt;</span><span class="hljs-tag">&lt;/<span class="hljs-name">obfuscate-link</span>&gt;</span></span></code></span></pre>


<p>Finally, you can utilize both the Astro component and the Web component throughout your Astro project.</p>


<pre class="wp-block-code"><span><code class="hljs language-javascript">
---
<span class="hljs-keyword">import</span> ObfuscateLink <span class="hljs-keyword">from</span> <span class="hljs-string">'./ObfuscateLink.astro'</span>;
---

<span class="xml"><span class="hljs-tag">&lt;<span class="hljs-name">div</span> <span class="hljs-attr">class</span>=<span class="hljs-string">"card"</span>&gt;</span>
  <span class="hljs-tag">&lt;<span class="hljs-name">p</span>&gt;</span>
    Email: <span class="hljs-tag">&lt;<span class="hljs-name">ObfuscateLink</span> <span class="hljs-attr">email</span>=<span class="hljs-string">"info@example.com"</span> /&gt;</span>
  <span class="hljs-tag">&lt;/<span class="hljs-name">p</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">div</span>&gt;</span></span></code></span></pre>


<p>The complete code can be seen in this Gist: </p>



<p><a href="https://gist.github.com/ivoba/222d5a49ad4542392772195c5e5ad032" target="_blank" rel="noopener" title="">https://gist.github.com/ivoba/222d5a49ad4542392772195c5e5ad032</a></p>The post <a href="https://nerdpress.org/2025/02/07/obfuscatelink-web-component-in-astro/">ObfuscateLink Web Component in Astro</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Obfuscate Web Component</title>
		<link>https://nerdpress.org/2023/12/08/obfuscate-web-component/</link>
		
		<dc:creator><![CDATA[Ivo Bathke]]></dc:creator>
		<pubDate>Fri, 08 Dec 2023 17:21:01 +0000</pubDate>
				<category><![CDATA[Astro]]></category>
		<category><![CDATA[Web components]]></category>
		<guid isPermaLink="false">https://nerdpress.org/?p=3281</guid>

					<description><![CDATA[<p>Typically, when integrating emails into websites, I obfuscate the email address to prevent spam bots from collecting them. For React, there were already components that handled this task; however, without React, I couldn&#8217;t find a suitable solution. Therefore, I created a web component: obfuscate-wc that now provides an HTML element capable of obfuscating your email &#8230; </p>
<p class="link-more"><a href="https://nerdpress.org/2023/12/08/obfuscate-web-component/" class="more-link">Continue reading<span class="screen-reader-text"> "Obfuscate Web Component"</span></a></p>
The post <a href="https://nerdpress.org/2023/12/08/obfuscate-web-component/">Obfuscate Web Component</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></description>
										<content:encoded><![CDATA[<p>Typically, when integrating emails into websites, I obfuscate the email address to prevent spam bots from collecting them. For React, there were already components that handled this task; however, without React, I couldn&#8217;t find a suitable solution.</p>



<p>Therefore, I created a web component: <a href="https://github.com/ivoba/obfuscate-wc" target="_blank" rel="noopener" title="">obfuscate-wc</a> that now provides an HTML element capable of obfuscating your email (and some other contact data).</p>


<pre class="wp-block-code"><span><code class="hljs language-xml"> <span class="hljs-tag">&lt;<span class="hljs-name">obfuscate-link</span> <span class="hljs-attr">id</span>=<span class="hljs-string">"obfuscate"</span> <span class="hljs-attr">email</span>=<span class="hljs-string">"aXZvQGxvY2FsLmRldg=="</span>&gt;</span>custom link<span class="hljs-tag">&lt;/<span class="hljs-name">obfuscate-link</span>&gt;</span></code></span></pre>


<span id="more-3281"></span>



<p>The component accepts an encoded email address, rendering it human-readable after events that typically align with human browsing behavior. <br />Custom decoders can be configured, with the default set to base64. <br />While sophisticated spam crawlers may still manage to decode the email, the likelihood decreases as you customize your encoder/decoder. It&#8217;s worth noting that the decoder could also be crawled, but the assumption is that this presents too much effort for the crawlers.</p>



<p>Using the web component itself is already blocking spammer that just look for mailto links.</p>



<p>How did I get there?</p>



<p>When using React I took this React component: <a href="https://github.com/coston/react-obfuscate" target="_blank" rel="noopener" title="">https://github.com/coston/react-obfuscate</a></p>



<p>In a new project, I began using <a href="https://astro.build/" target="_blank" rel="noopener" title="">Astro</a>, and React became unnecessary. However, I found myself missing the obfuscation component. Consequently, I chose to create a web component with similar functionality. This endeavor also served as a valuable exploration into web components. Web components, native to the browser, enable you to define your own HTML tags with specific functionality within the component.</p>



<p>Since the API of the web components is not the nicest, let&#8217;s say.<br />I took <a href="https://stenciljs.com/" target="_blank" rel="noopener" title="">StencilJs</a> which is a framework for Web Component development.<br />It also comes with nice tooling like Typescript support, tests and builds helpers.</p>



<p>I crafted it with Stencil, learned the process of building the component&#8211;admittedly, this was a bit cumbersome&#8211;but now it&#8217;s ready for use in any web application.</p>The post <a href="https://nerdpress.org/2023/12/08/obfuscate-web-component/">Obfuscate Web Component</a> first appeared on <a href="https://nerdpress.org">Nerdpress.org</a>.]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
