This Dot Blog
This Dot provides teams with technical leaders who bring deep knowledge of the web platform. We help teams set new standards, and deliver results predictably.
AI (Probably) Won’t Ruin Your Engineering Career with Ben Lesh, Adam Rackis, & Tracy Lee
In this episode of the Modern Web Podcast, hosts Tracy Lee, Ben Lesh, and Adam Rackis kick things off by discussing the progress of observables landing in the browser and the potential impact it could have on the use of RXJS. As developers, we're always on the lookout for new tools and technologies that can make our lives easier, and observables in the browser certainly have the potential to do just that. They talk about whether or not you should listen to your “customers” or have a strong vision that you want to push forward, like Ryan Carniato and his approach with Solid and Signals. The three also talk about AI tools, such as GPT and Co-Pilot, and how they are shaping the future of coding and ideation. Finally, Ben, Adam, and Tracy briefly touch on the potential impact of automation on job roles and the outsourcing of tech jobs. While automation can streamline certain tasks, it's important to remember that human creativity and problem-solving skills are irreplaceable. Download this episode here!...
Feb 16, 2024
Next.js Route Groups
Learn how to organize and optimize your application routing with ease. Say goodbye to messy routes and hello to a more intuitive and maintainable structure with the new Next.js Group Routes!...
Feb 7, 2024
Demystifying React Server Components
React Server Components (RSCs) are the latest addition to the React ecosystem, and they've caused a bit of a disruption to how we think about React....
Feb 2, 2024
New Web APIs, CSS, Tailwind, and RSC with Chance Strickland, Ben Lesh, Adam Rackis, and Tracy Lee
Tracy Lee, Adam Rackis, and Ben Lesh host special guest Chance Strickland to discuss topics around new web APIs, CSS, Tailwind, and react server components. They go into detail about a new web API that allows the implementation of dark mode to be really easy, and get excited about how many of these new APIs open up new possibilities for creating user-friendly interfaces that adapt to individual preferences. Chance is curious about the implementation of React Server Components, and how RSCs will be implemented across the React world, and what the implementations will ultimately look like and how wildly different they may be from company to company. Will a standard emerge? Chance also shares his excitement for advancements in CSS and the ability to achieve complex effects with simpler code. And of course, they don’t miss the chance to talk about Tailwind’s tradeoffs and advantages. The four of them emphasize the importance of staying curious and constantly seeking better ways to approach coding tasks. This mindset is crucial in an ever-evolving field like web development. By embracing new technologies and staying open to learning, developers can stay ahead of the curve and deliver exceptional results. Listen to the full episode here: https://modernweb.podbean.com/e/modern-web-podcast-s11e20-new-web-apis-css-tailwind-and-rsc-with-chance-strickland-ben-lesh-adam-rackis-and-tracy-lee/...
Jan 31, 2024
Can Vercel Fix React?
Tracy Lee, Ben Lesh and Adam Rackis discuss the current state of React and its potential future. React and Vercel: A Positive Change? One of the key topics of conversation revolves around React and its relationship with Vercel. It's worth noting that high-profile React core team members have recently made the move to Vercel, which many see as a positive change. This move brings fresh perspectives and expertise to the project, potentially leading to exciting developments in the future. However, the hosts also acknowledge the challenges of upgrading to React 18, as there are still many users on older versions. Upgrading can have a significant impact on tests and requires careful consideration. It's clear that React's evolution is an ongoing process, and the community plays a crucial role in shaping its future. The Potential of Bun: A New Default Runtime for Node Development Is there potential for the runtime called Bun to become the default for node development? Ben expresses skepticism about this possibility, highlighting the need for perfect execution and widespread community support. Switching to a new runtime involves extensive testing and potential risks, especially for critical financial services. On the other hand, Adam presents a more optimistic view, emphasizing the advantages, such as its built-in TypeScript support and improved interop with node. He believes that as Bun continues to grow and improve, and could become a compelling option for new projects. The Future of Front-End Development: Likability and AI They also share their thoughts on the future of front-end development and various technologies. They highlight the importance of likability and the team behind a project, as these factors can greatly influence its success. Additionally, they discuss the potential impact of AI on framework development, raising interesting questions about the role of automation in shaping the future of web development. While React is praised for its strengths, its perceived limitations compared to other frameworks are also mentioned. The advancements in state management in Angular are highlighted, showcasing the continuous evolution of front-end technologies and the need for developers to stay adaptable and open to new possibilities. Listen to the full podcast here: https://modernweb.podbean.com/e/modern-web-podcast-s11e20-can-vercel-fix-react-a-conversation-with-tracy-lee-ben-lesh-adam-rackis/...
Jan 25, 2024
Deploying Multiple Apps From a Monorepo to GitHub Pages
Explore deploying multiple front-end applications on GitHub Pages with our guide. Learn how to navigate the challenges of client-side routing and efficiently manage multiple apps in one repository....
Jan 24, 2024
Building interactive forms with TanStack Form
Discover the power of TanStack Form, a new headless form library that simplifies building complex, interactive forms....
Jan 12, 2024
File Based Routing with Expo Router
Learn about Expo Router, a file-based solution for React Native and web apps, enabling seamless navigation across screens using uniform components on Android, iOS, and web....
Jan 10, 2024
Does Replay Fix All Debugging Issues?
Rob Ocel and Adam Barrett talk with Jason Laster, CEO and co-founder of Replay. For those of you who are unfamiliar, Replay is an innovative browser development tool that is revolutionizing the way developers approach time travel debugging and bug fixing. This episode highlights all the reasons why Replay is such an amazing tool and all the problems it solves for developers. Jason shares the background on where the concept of time travel debugging came from, and how it actually works in Replay. The idea that you can capture a bug once and replay it as many times as needed enables developers to zoom in and identify the root cause of the issue. This approach saves infinite time, as you no longer have to rely on guesswork or spend hours reproducing bugs. Download this podcast episode here!...
Jan 5, 2024
Building a Multi-Response Streaming API with Node.js, Express, and React
Introduction As web applications become increasingly complex and data-driven, efficient and effective data transfer methods become critically important. A streaming API that can send multiple responses to a single request can be a powerful tool for handling large amounts of data or for delivering real-time updates. In this article, we will guide you through the process of creating such an API. We will use video streaming as an illustrative example. With their large file sizes and the need for flexible, on-demand delivery, videos present a fitting scenario for showcasing the power of multi-response streaming APIs. The backend will be built with Node.js and Express, utilizing HTTP range requests to facilitate efficient data delivery in chunks. Next, we'll build a React front-end to interact with our streaming API. This front-end will handle both the display of the streamed video content and its download, offering users real-time progress updates. By the end of this walkthrough, you will have a working example of a multi-response streaming API, and you will be able to apply the principles learned to a wide array of use cases beyond video streaming. Let's jump right into it! Hands-On Implementing the Streaming API in Express In this section, we will dive into the server-side implementation, specifically our Node.js and Express application. We'll be implementing an API endpoint to deliver video content in a streaming fashion. Assuming you have already set up your Express server with TypeScript, we first need to define our video-serving route. We'll create a GET endpoint that, when hit, will stream a video file back to the client. Please make sure to install cors for handling cross-origin requests, dotenv for loading environment variables, and throttle for controlling the rate of data transfer. You can install these with the following command: ` ` In the code snippet above, we are implementing a basic video streaming server that responds to HTTP range requests. Here's a brief overview of the key parts: 1. File and Range Setup: We start by determining the path to the video file and getting the file size. We also grab the range header from the request, which contains the range of bytes the client is requesting. 2. Range Requests Handling: If a range is provided, we extract the start and end bytes from the range header, then create a read stream for that specific range. This allows us to stream a portion of the file rather than the entire thing. 3. Response Headers: We then set up our response headers. In the case of a range request, we send back a '206 Partial Content' status along with information about the byte range and total file size. For non-range requests, we simply send back the total file size and the file type. 4. Data Streaming: Finally, we pipe the read stream directly to the response. This step is where the video data actually gets sent back to the client. The use of pipe() here automatically handles backpressure, ensuring that data isn't read faster than it can be sent to the client. With this setup in place, our streaming server is capable of efficiently delivering large video files to the client in small chunks, providing a smoother user experience. Implementing the Download API in Express Now, let's add another endpoint to our Express application, which will provide more granular control over the data transfer process. We'll set up a GET endpoint for '/download', and within this endpoint, we'll handle streaming the video file to the client for download. ` This endpoint has a similar setup to the video streaming endpoint, but it comes with a few key differences: 1. Response Headers: Here, we include a 'Content-Disposition' header with an 'attachment' directive. This header tells the browser to present the file as a downloadable file named 'video.mp4'. 2. Throttling: We use the 'throttle' package to limit the data transfer rate. Throttling can be useful for simulating lower-speed connections during testing, or for preventing your server from getting overwhelmed by data transfer operations. 3. Data Writing: Instead of directly piping the read stream to the response, we attach 'data' and 'end' event listeners to the throttled stream. On the 'data' event, we manually write each chunk of data to the response, and on the 'end' event, we close the response. This implementation provides a more hands-on way to control the data transfer process. It allows for the addition of custom logic to handle events like pausing and resuming the data transfer, adding custom transformations to the data stream, or handling errors during transfer. Utilizing the APIs: A React Application Now that we have a server-side setup for video streaming and downloading, let's put these APIs into action within a client-side React application. Note that we'll be using Tailwind CSS for quick, utility-based styling in our components. Our React application will consist of a video player that uses the video streaming API, a download button to trigger the download API, and a progress bar to show the real-time download progress. First, let's define the Video Player component that will play the streamed video: ` In the above VideoPlayer component, we're using an HTML5 video tag to handle video playback. The src attribute of the source tag is set to the video endpoint of our Express server. When this component is rendered, it sends a request to our video API and starts streaming the video in response to the range requests that the browser automatically makes. Next, let's create the DownloadButton component that will handle the video download and display the download progress: ` In this DownloadButton component, when the download button is clicked, it sends a fetch request to our download API. It then uses a while loop to continually read chunks of data from the response as they arrive, updating the download progress until the download is complete. This is an example of more controlled handling of multi-response APIs where we are not just directly piping the data, but instead, processing it and manually sending it as a downloadable file. Bringing It All Together Let's now integrate these components into our main application component. ` In this simple App component, we've included our VideoPlayer and DownloadButton components. It places the video player and download button on the screen in a neat, centered layout thanks to Tailwind CSS. Here is a summary of how our system operates: - The video player makes a request to our Express server as soon as it is rendered in the React application. Our server handles this request, reading the video file and sending back the appropriate chunks as per the range requested by the browser. This results in the video being streamed in our player. - When the download button is clicked, a fetch request is sent to our server's download API. This time, the server reads the file, but instead of just piping the data to the response, it controls the data sending process. It sends chunks of data and also logs the sent chunks for monitoring purposes. The React application collects these chunks and concatenates them, displaying the download progress in real-time. When all chunks are received, it compiles them into a Blob and triggers a download in the browser. This setup allows us to build a full-featured video streaming and downloading application with fine control over the data transmission process. To see this system in action, you can check out this video demo. Conclusion While the focus of this article was on video streaming and downloading, the principles we discussed here extend beyond just media files. The pattern of responding to HTTP range requests is common in various data-heavy applications, and understanding it can be a useful tool in your web development arsenal. Finally, remember that the code shown in this article is just a simple example to demonstrate the concepts. In a real-world application, you would want to add proper error handling, validation, and possibly some form of access control depending on your use case. I hope this article helps you in your journey as a developer. Building something yourself is the best way to learn, so don't hesitate to get your hands dirty and start coding!...
Aug 9, 2023
Challenges of SSR with SolidStart and TanStack Query v4
Coming from developing in React, a lot of us are big fans of TanStack Query. It adds that layer for async data fetching to React we needed. So when shifting to a new framework, Solid, which has a familiar signature as React, we wanted to bring our beloved tools with us. During the development of our showcase, we came to realize that the combination of TanStack Query (v4, v5 seems to include positive changes) and SolidStart was not meant to be. Understanding the differences Different interface Right out of the box, the experience between Solid and React differs. There’s the first very obvious issue that the documentation for Solid consists of a single page, whereas React gets a full book on documentation. But more important is the way one uses TanStack Query. React directly takes the tuple containing the query name and variables. Where Solid, due to the way reactivity works, needs a function returning the tuple. This way, Solid can bind an effect to the query to ensure it triggers when the dependencies change. It’s not a big difference, but it indicates that TanStack Query React and TanStack Query Solid are not the same. ` — TanStack Query Docs Stores What is not so apparent from the documentation are the changes under the hood. React triggers rerenders when state changes are pushed. These rerenders will, in turn, compare the new variables against dependencies to determine what to run. This does not require special treatment of the state. Whatever data is passed to React will be used directly as is. Solid, on the other hand, requires Signals to function. To save you the hassle, TanStack will create stores from the returned data for you. With the dependency tuple as a function and the return value as store, TanStack Query closes the reactivity loop. Whenever a signal changes, the query will be triggered and load new data. The new data gets written to the store, signalling all observers. Why it doesn’t work Solid comes prepacked with Resources. These basically fill the same functionality as TanStack Query offers. Although TanStack does offer more features for the React version. Resources are Signal wrappers around an async process. Typically they’re used for fetching data from a remote source. Although both Resources and TanStack Query do the same thing, the different signatures makes it so they’re not interchangeable. Resources have loading where TanStack uses isLoading. SolidStart SolidStart is an opinionated meta-framework build on top of SolidJS and Solid router. One of the features it brings to the table is Server-side rendering (SSR). This sends a fully rendered page to the client, as opposed to just sending the skeleton HTML and having the client build the page after the initial page load. With SSR, the server also send additional information to the client for SolidJS to hydrate and pick up where the server left off. This prevents the client from re-rendering all the work the server had already done. In order for SSR to work, one needs to create pages. SolidStart offers a feature that allows developers to inject data into their pages. By doing so, one can set up a generic GUI for loading data when changing between pages. A very minimal example of this looks like: ` When combining this setup with routing and createResource, there’s some caveats that need to be taken into consideration. These are described in the official SolidStart docs. In order to keep the routes maintainable, SolidStart offers createRouteData that simplifies the setup and to mitigate potential issues caused by misusing the system. createRouteData, resources and TanStack Query It is with createRouteData that we run into issues with combining SolidStart and TanStack Query. In order to use SSR, SolidStart needs the developers to use createRouteData. Which in turn expects to create a resource for the async operation that is required to load the page’s data. By relying on a resource being returned, SolidStart can take control of the flow. It knows when it’s rendering on the server, how to pass both the HTML and the data to server, and finally how to pick up on the client. As stated before, TanStack Query relies on stores, not on resources. Therefore we cannot swap out createRouteData and createQuery even though they both fill the same purpose. Our initial attempt was to wrap the returned data from createQuery to resemble the shape of a resource. But that started to throw errors as soon as we tried to load a page. Under the hood, both SolidStart and TanStack Query are doing their best to hold control over the data flow. Systems like caching, hydration strategies and refetching logic are running while it seems like we’re just fetching data and passing it to the render engine. These systems conflict (they both are trying to do the same thing and get stuck in a tug-o-war for the data). This results in a situation where we can either satisfy TanStack Query or SolidStar. We can probably make it work by creating an advanced adapter that awaits and pulls the data from a query. Use that data to create our own resource and feed that to createRouteData to have SolidStart do its thing. Our conclusion is that there’s too much effort needed to create and maintain such an adapter especially when taking into consideration that we can simply move away from TanStack Query (for now) and use resources as SolidStart intents....
Jul 7, 2023
How to Integrate Mailchimp Forms in a React Project
Intro Today we will cover how to set up an email signup form using React and Mailchimp. This blog will be using the starter.dev cra-rxjs-styled-components template to expedite the process. This article assumes you have a basic understanding of React, and have set up a Mailchimp account. Here is the code repo if you want to review it while reading, or just skip ahead. We will start with setting up our React project using Starter.dev for simplicity, and then finish it up by integrating the two for our signup form. To start, we will be using the command yarn create @this-dot/starter --kit cra-rxjs-styled-components, which can be found here. We’ll go ahead, and give the project a name. I will be calling mine react-mailchimp. Now we will navigate into the project and do a yarn install. Then we can run yarn run dev to get it up and running locally on localhost:3000. This should have us load up on the React App, RxJS, and styled-components Starter kit page. With that all set, we’ll also need to install jsonp by using yarn add jsonp. We’ll be using jsonp instead of fetch to avoid any CORS issues we may run into. This also makes for an easy and quick process by not relying on their API, which can’t be utilized by the client. Now that we have our project set up, we will go ahead and go and grab our form action URL from MailChimp. This can be found by going to your Audience > Signup Forms > Embedded Forms > Continue and then grabbing the form action URL found in the Embedded Form Code. We need to make a small change to the URL and swap /post? with /post-json?. We can now start setting up our form input, and our submit function. I will add a simple form input and follow it up, and a submit function. Inside the submit function, we will use our imported jsonp to invoke our action URL. ` We’ll also add a quick alert to let the user know that it was successful and that’s it! We’ve now successfully added the email to our MailChimp account. Conclusion Today, we covered how to integrate Mailchimp with a react app using the cra-rxjs-styled-components template from starter.dev. I highly recommend using starter.dev to get your project up and running quickly. Here is the code repo again for you to check out....
Jul 5, 2023