#Is this the right way to make a reusable component in Astro ?
4 messages · Page 1 of 1 (latest)
In Astro, you can indeed create reusable components. However, without seeing your specific Button component code, it's hard to provide a precise answer.
Generally, if you have a script tag inside your Astro component, it will be included every time you use that component. This could potentially lead to the script being duplicated if the component is used multiple times on a page.
However, Astro also supports the concept of Web Components (https://docs.astro.build/en/guides/client-side-scripts#web-components-with-custom-elements), which allows you to define custom behavior for your HTML elements. This can be a good way to encapsulate the behavior of your component and avoid unnecessary duplication of scripts.
Here's an example of how you might define a custom element in Astro:
<astro-button>
<button aria-label="Button">Click me</button>
</astro-button>
<script>
class AstroButton extends HTMLElement {
constructor() {
super();
// Define your button behavior here
}
}
customElements.define('astro-button', AstroButton);
</script>
In this example, the constructor() method of our custom element (astro-button) will run each time an astro-button is found on the page. This allows you to write code for one component at a time, even if you intend to use this component multiple times on a page.
For your specific use case of obfuscating links, you might want to consider using a web component or a similar approach to encapsulate the obfuscation logic. This would ensure that the script is not unnecessarily duplicated.
Remember, the best practice is to minimize the amount of JavaScript sent to the client to ensure optimal performance. Astro's design philosophy emphasizes this, encouraging developers to only send the minimal amount of JavaScript necessary.
import { storyblokEditable } from '@storyblok/astro';
import { ButtonStoryblok } from './types/storyblok';
interface AstroProps {
blok: ButtonStoryblok;
}
const { blok } = Astro.props as AstroProps;
const obfuscatedLink = Buffer.from(blok.href as string, 'utf-8').toString('base64');
---
{
blok.isObfuscated ? (
<div
class="button-link cursor-pointer"
data-location={obfuscatedLink}
{...storyblokEditable(blok)}
>
{blok.title}
</div>
) : (
<a {...storyblokEditable(blok)} href={blok.href}>
{blok.title}
</a>
)
}
{blok.isObfuscated && (
<script>
const buttons = document.querySelectorAll('.button-link');
buttons.forEach((button) => {
button.addEventListener('click', () => {
const location = button.getAttribute('data-location');
window.location.href = atob(location);
});
});
</script>
)}