Switch Theme

Al Reasat Rafio, JAMstack and Headless Solutions Expert, not Al Reasat Radio. You've found the correct website.
AR

Al Reasat Rafio

Founder. Developer. Student.

Blog - Al Reasat Rafio

I share what I learn—tech insights, web dev tips, and the occasional “oops” moment. Stay updated, pick up cool skills, and maybe even have a laugh along the way! (ง’̀-‘́)ง

Building Blocks

Breaking Down Complexity: The Power of Compound Components

Ah, the classic "throw-everything-in-a-component" approach. We've all been there. Your Card component starts off innocent enough, but soon it's a tangled mess of conditionals, a boolean flag buffet. It's like trying to raise a teenager with a million rules – confusing for everyone involved. In this article, we'll explore the concept of compound components and why they're a game-changer for keeping your sanity and your code organized. The Struggles of the Monolithic Card Imagine your Card component, initially a simple rectangle of information. You start with a simple component, and before you know it, you're passing a dozen props and using a bunch of boolean flags to control its behavior. It's like trying to control a puppet show with a hundred strings attached. Take the following example: At first glance, this might seem like a reasonable way to control the behavior of your component. But as your component grows in complexity, you'll find yourself writing more and more conditional statements to handle all the different scenarios. This approach is like trying to control your kid's every move. They rebel, the code becomes unreadable, and you question all your life choices. Enter the Compound Component Pattern The compound component pattern is a design approach that involves breaking down a complex component into smaller, reusable pieces. Instead of passing a bunch of props and using boolean flags, you create separate components for each piece of the puzzle. It's like letting your children (components) express themselves – within structured boundaries. Here's an example of how you might implement the compound component pattern in React: See that? No more boolean flags! We define child components like Card.Image, Card.Info, and Card.Button. They live within the Card component, but have their own autonomy. You, as the parent component, can choose which child components to include. Think of it like letting your kid pick their outfit (within some reasonable guidelines, of course). It fosters creativity and a happier, more maintainable codebase. Svelte Joins the Compound Fun Svelte takes a similar approach: Slots and named components allow you to customize your Card while keeping the core structure clear. Peace and harmony in the codebase, achieved! The Benefits of Compound Components So, why should you consider using compound components? Here are a few benefits: Easier to maintain: With compound components, you can update individual components without affecting the entire component tree. More reusable: Compound components can be reused across multiple components, reducing code duplication. Easier to extend: Compound components make it easier to add new features or functionality without modifying the underlying component. Taking it Further For even more complex components, consider using React's Context API or Svelte's stores. Think of it like letting your child have a say in family rules (within reason, still the parent!). Conclusion In this article, we've explored the concept of compound components and why they're a better approach than traditional components. By breaking down complex components into smaller, reusable pieces, you can create more maintainable, reusable, and extendable code. So, the next time you're faced with a complex component, consider breaking it down into smaller pieces. Your sanity (and your code) will thank you. Cheers! 🍻

Mar 10, 2025
SvelteKitReact

What PayloadCMS Taught Me About Shortcuts on Big Projects

Let me tell you about the fastest I've ever started a project, and how that speed quietly turned into the slowest middle I've ever lived through. The shortcut that felt like cheating The project was a large OTA-style travel platform. Multiple front-ends (a B2B portal, a B2C site), an admin to run them, application forms, document verification, the works. Plenty of surface area. So at the very start, I made a decision that felt incredibly smart. I didn't build a backend at all. I reached for PayloadCMS and ran everything through it. If you haven't used it, Payload is a TypeScript-first headless CMS where you define your data as "collections," and it hands you a backend and a polished admin UI for free. And I do mean free. You describe the shape of your data, and the dashboard, the auth, the REST and GraphQL APIs, the relationships, all of it just appears. That solved two real problems in one move. It gave the team a genuine CMS to edit content and filters, and it gave me an admin UI without me building a single screen. For the first stretch of the project, it was glorious. We moved *fast*. Features that would normally take days were taking hours. I was convinced I had outsmarted the work. Where it started to hurt Then the project did what every serious project does. It got complicated. The flows we needed stopped looking like "edit a record." We needed multi-step verification where each stage gated the next. We needed custom logic woven deep into how data was created and validated. We needed the admin experience to behave in ways that didn't map cleanly onto "a form for a collection." And slowly, the relationship flipped. Instead of Payload doing the work for me, I was doing work for Payload. I was fighting its architecture to build the things I actually wanted, bending the tool around requirements it was never shaped for. Every custom requirement turned into a research project: can Payload even do this, and if so, how much do I have to contort to get there? The speed was gone. I just hadn't admitted it yet. The escape hatch that wasn't Here's the part I want you to really hear, because it's the trap inside the trap. When a tool starts fighting you, the obvious move is a compromise: keep the tool for the easy 80%, and build the hard 20% separately. Keep Payload for the simple content, and stand up something custom next to it for the complex flows. It sounds reasonable. It is a disaster. The moment you have two systems, you have a boundary between them, and that boundary needs to stay in sync. Data lives in two places. You write glue code to shuttle it back and forth. The two systems drift, and you write more glue to reconcile them. Now you're not maintaining one backend or even two backends. You're maintaining two backends and the fragile seam between them. The "fast" option had quietly become the slowest possible architecture. I had all the constraints of Payload and all the work of a custom backend, with a synchronization headache stapled on top. Ripping it out So I made the call that, in hindsight, I should have made earlier. I ripped Payload out and built the backend myself. It was more work up front, no question. But for the first time on that project, the tool stopped being the bottleneck. When I needed a weird flow, I just built the weird flow. No contorting, no research project, no seam to babysit. The lesson I keep relearning Let me be very clear about something: this is not a knock on Payload. It is a genuinely excellent tool, and it did exactly what it promises. The mistake wasn't choosing Payload. The mistake was choosing it for the wrong project. So here's the rule I use now, and it applies far beyond Payload. It's true of any "instant backend," any low-code platform, any tool that trades flexibility for speed. If you already know a project is going to be complex and highly custom, and you have the team and the ability to build the real thing, build the real thing. Pay the cost up front. Buy the foundation. When the shortcut is the right call To keep myself honest, the inverse is just as important, because "always build it yourself" is its own expensive mistake. Reach for the shortcut when: You're validating an idea and speed matters more than the ceiling. The project genuinely *is* mostly content and CRUD, and you have good reason to believe it'll stay that way. You don't have the team or time to build and maintain a custom backend. The cost of being wrong is small, because you can throw it away cheaply. Payload is a fantastic fit for all of those. I'd reach for it again tomorrow on the right project. I'd just never again hand it a project I already knew was going to outgrow it. May your shortcuts be the right ones! 🍻

Jun 29, 2026
Payload CMSArchitectureLessonsBackend

Implement simple and efficient pagination in SvelteKit with Sanity.io

Pagination is an essential feature for managing large sets of content in web applications. Here’s a breakdown of how I like to approach pagination and why it works well in different scenarios. Setting Up Pagination in page.ts The first step for me is always to create the pagination logic in page.ts or page.server.ts. This is where I calculate the total number of pages, determine the items per page, and query the data accordingly. Query From Sanity for Paginated Blogs Breaking It Down Pagination Logic: Here, I’m calculating the current page from the URL query parameters. If no page parameter is passed, it defaults to page=1. Items per Page: I’ve set the perPage variable to 6, which means I’m displaying six blog posts per page. Sanity Query: I use a groq query to pull the blog data and count the total number of blogs to figure out how many pages we need. Learn more about groq. Caching: The setHeaders function adds caching headers to make sure the response is cached for a good period, so users won’t have to wait for the data to be fetched again for the same page. Learn more about setHeaders Creating the Pagination Component Now that we have the pagination logic in place, it’s time to create a reusable pagination component in Svelte. This component will render the page buttons and handle the logic for navigating between pages. The navigateTo function updates the page query parameter in the URL and navigates to the new page. This is what triggers the SvelteKit page load and the data-fetching logic to re-fetch the content based on the selected page. And that’s it! You now have a functional, efficient pagination system in your SvelteKit + Sanity.io project.

Apr 1, 2025
SvelteKitSanity
SvelteKit and React Logo

Getting Started with Svelte 5: A Guide for React Developers

The Svelte team announced the release of version 5 on October 20, 2024 🎉🎉, bringing several exciting new features and enhancements for developers. This latest version continues to build on Svelte's reputation for simplicity and performance, making it even more appealing to modern web developers. In this guide, we'll cover the basics of Svelte 5 and help you understand how to transition smoothly from React. What is Svelte(Kit)? Svelte is yet another single-page application (SPA) framework in the growing landscape of JavaScript frameworks. Opsi No. Svelte is not a framework but a compiler. It compiles your component code for single-page applications (SPAs) at build time into highly optimized vanilla JavaScript, which is what runs in your browser. This means less runtime overhead and better performance out of the box. SvelteKit extends Svelte by providing a complete toolkit for building web applications, including features like routing, server-side rendering (SSR), static site generation (SSG), and client-side rendering (CSR). Why Should React Developers Care About Svelte? SvelteKit is gaining popularity for its simplicity and performance. If you've worked with React, you've probably encountered situations where the overhead of managing state, using hooks, and dealing with performance bottlenecks became challenging. SvelteKit offers a lighter approach with fewer dependencies, faster builds, and a cleaner syntax. Svelte is based on HTML rather than JS. Key Differences Between React and SvelteKit (Basics) Simple Component Svelte’s writing form is a little weird for React developers because there is no JSX or wrapped components. React Example: Note: Adding types to useState and using useEffect to double the value is not necessary in this case. We included them here simply to follow a common pattern in React. Svelte Example: Svelte's syntax is cleaner, and there's no need for hooks like useState to manage component state. Instead, Svelte uses signals to create reactive state, allowing you to update the state effortlessly. You don’t need to import anything in SvelteKit; simply use $state, and it magically handles reactivity for you. Additionally, Svelte offers $derived to create derived state that relies on other state variables. The expression inside $derived(...) should not have side effects, and it will automatically re-run whenever any of the values it depends on change, making it easy to calculate new values based on the current state. Side Effects In Svelte 5, you can use $effect and $effect.pre to manage side effects in your components, which can be compared to React's useEffect and useLayoutEffect hooks. Svelte $effect and $effect.pre $effect runs after the component is mounted and whenever its dependencies (like $state or $derived) change. It executes after the DOM updates. Example: A cleanup function can be returned, executing before the next effect or on unmount. Also to prevent something from being treated as an $effect or $derived dependency, you can use untrack: $effect.pre runs before the component is mounted and whenever its dependencies change, executing right before the DOM updates. Example: Svelte automatically tracks dependencies, simplifying state management compared to React's useEffect and useLayoutEffect hooks. This built-in tracking also helps prevent common beginner mistakes that can lead to unexpected behavior, or as some say, "shooting yourself in the foot." Loop In Svelte, you can use the {#each} block to create loops, which is concise and integrates seamlessly with the reactivity system: Svelte automatically optimizes updates to the DOM, efficiently re-rendering only the elements that change. In React, loops are typically implemented using the map() method within JSX: Unlike React, which requires a key prop for each item to identify changes, additions, or removals—facilitating optimal reconciliation with the virtual DOM—Svelte handles updates automatically without the need for explicit keys. React's useRef and Svelte's Binding Mechanism In React, the useRef hook is commonly used to directly interact with DOM elements or to store mutable values without triggering re-renders. It allows you to maintain a reference to a DOM node and access it imperatively: In Svelte, you can achieve similar functionality using the bind:this directive: you're not limited to just bind:this for DOM elements. You can also use bind for two-way binding of values, allowing you to synchronize state with input fields effortlessly. This binding allows you to directly connect a form input or other elements to a reactive variable without needing to manage refs explicitly: Svelte's Special Elements: Svelte have many useful special element. <svelte:window> This provides a unique syntax for adding event listeners to the window object using <svelte:window>. This special element simplifies global event handling within your Svelte components. Let's see an example how this is useful: Lets Implement this same thing with React React requires significantly more code to achieve the same functionality. Overall, Svelte's <svelte:window> component offers a more streamlined and declarative approach for handling global events like scrolling, while React provides flexibility and control, albeit with additional complexity in setup. <svelte:element> In Svelte, you can use the <svelte:element> tag to create dynamic elements. This allows you to specify which HTML element to render based on a variable or condition at runtime. Here's a simple example demonstrating how to use <svelte:element> to create dynamic elements: Here's a similar example in React: In the React example you might encounter compiler errors or lose autocompletion when using dynamic elements this way, especially if the compiler cannot infer the element type. In contrast, SvelteKit handles dynamic elements seamlessly, providing zero issues with autocompletion and type inference. Learn more about svelte's special elements: https://svelte.dev/docs/special-elements Props In Svelte, you can pass props directly to a component and access them using the $props keyword. In Svelte, passing props is quite similar to React, where the parent component sends data to the child component. However, I find Svelte's approach to be slightly better and more concise. Todo App Now Lets Make a simple todo app with Svelte and React Svelte way Now let's rebuild this with React The Svelte approach in the example feels much closer to raw HTML and JavaScript, offering a better developer experience (in my opinion). Give it a try, and you might just fall in love with the simplicity and efficiency of creating modern web applications with Svelte! I have just covered the basics; for more in-depth information, I recommend reading the SvelteKit documentation. Conclusion Svelte(Kit) offers React developers a fresh and efficient way to build modern web applications. Its simplicity, performance, and built-in features like SSR, SSG, and scoped styling make it an exciting alternative to React and Next.js. While the learning curve is gentle, SvelteKit's approach can lead to cleaner, faster, and more maintainable code. If you’re a React developer looking to explore something new, give SvelteKit a try. Its simplicity and power may just win you over!

Mar 11, 2025
SvelteKitReact

Svelte Reactive Context: How to Share Data Within Child Components the Right Way

The Problem I Faced Let me share a situation that probably sounds familiar to many developers. I was building a moderately complex application with nested components, and I needed to share state across multiple parts of my UI. My first instinct was to create some global states: This worked initially. I imported that class wherever I needed them. But as my application grew, I started running into problems: Manual cleanup required: I had to remember to unsubscribe from stores to prevent memory leaks Global state pollution: Every component could access and modify any store Multiple instances confusion: When I needed multiple instances of the same component, they would conflict by using the same global state The worst part was debugging issues when components would unexpectedly update because some distant part of my application modified a store I was subscribed to. I needed a better solution. Discovering Svelte Context API with Classes After some research, I found a cleaner approach combining Svelte's Context API with classes. Here's a simple example that changed my workflow: Implementation in my components: Why This Approach Is Better ? This pattern solved all my previous problems: No manual cleanup: The context is tied to component lifecycle and gets cleaned up automatically when components are destroyed Scoped access: Only components within the tree where context is created can access it Multiple instances work: I could create separate contexts for different component trees The biggest win was that my code became much more maintainable. I have many context i my app and each context have a clear purpose, and the class methods encapsulated all the related logic. When I needed to debug issues, I could easily trace the flow of data changes through the class methods. Context with reactive classes has become my go-to pattern for sharing state in Svelte applications. It provides the perfect balance between isolation and accessibility, making my code more maintainable and easier to understand. If you're still using global stores for everything, I highly recommend giving this approach a try. It might just transform your Svelte development experience as it did mine.

Mar 17, 2025
SvelteKitContext ApiReactivity

Rendering Payload CMS Lexical Rich Text in SvelteKit

While working with Payload CMS and SvelteKit, I needed to render rich text content stored as Lexical JSON. Surprisingly, there wasn’t much guidance available, so after some trial and error, I found a simple and effective solution. Here’s how I did it just in case you are facing the same issue. Lexical JSON Instead of HTML Payload CMS stores rich text as Lexical JSON, which isn’t directly usable in a SvelteKit frontend. To display it properly, we need to convert it into HTML. Convert Lexical JSON to HTML Install the Required Package Convert and Render in SvelteKit Why This Works convertLexicalToHTML({ data: content }): Converts Lexical JSON into HTML. {@html contentHTML}: Injects the converted HTML into Svelte. And that’s it! With just a small tweak, your rich text content is properly rendered in SvelteKit. Hope this saves you some time—happy coding!

Apr 1, 2025
SvelteKitPayload CMS
© 2026 Created by Al Reasat Rafio