Skip to content

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.

Newest First
Advanced TypeScript - Schema Validation with Zod - Type Inference & Generics with Josh Goldberg cover image

Advanced TypeScript - Schema Validation with Zod - Type Inference & Generics with Josh Goldberg

In this episode of Modern Web, Josh Goldberg discusses the benefits of TypeScript ESLint v8 and as well as other various topics related to JavaScript tools, AI in coding, and industry dynamics. Josh breaks down the latest version of TypeScript ESLint, v8. He points out the big performance boosts and introduces the cool new feature of type-aware linting. With this, developers can catch potential errors and follow best practices by using TypeScript's static type checking. This not only cuts down on bugs but also makes the code easier to read and maintain. Tracy and Josh talk about the importance of using the right tools for better coding results. They discuss how the Gartner hype cycle can influence developers' choices and warn against adopting tools just because they’re trendy. Instead, they suggest carefully evaluating tools based on specific needs and project requirements. By picking the right tools, developers can simplify their workflows, improve code quality, and get better outcomes overall. The conversation also touches on the impact of companies like Vercel and the unexpected consequences in tech development. While new tools and technologies can be super beneficial, they can also bring unexpected challenges. It’s important for developers to be aware of these potential issues and address them to ensure smooth development and successful projects. They also chat about the "trough of disillusionment" in tech adoption and mention upcoming typed linting tools which aim to further improve code quality and developer productivity. Lastly, the two talk about the SquiggleConf conference, which focuses on web development tools. They explain the term "squiggle" in error indicators and why clear, informative error messages are important for helping developers debug and troubleshoot. The conference is a great place for developers to learn about the latest web development tools and share tips on improving the developer experience. Check it out https://2024.squiggleconf.com/ on October 3-4, 2024 in Boston, MA!...

I Broke My Hand So You Don't Have To (First-Hand Accessibility Insights) cover image

I Broke My Hand So You Don't Have To (First-Hand Accessibility Insights)

A perspective of a temporarily impaired developer on accessibility both from the perspective of a user and of a software engineer. Using the web disabled “surprisingly” makes you think about people’s experience on the web. Let us take you on that journey!...

Understanding Vue's Reactive Data cover image

Understanding Vue's Reactive Data

A blog post that unravel how Reactivity works in Vue 3...

Performance Analysis with Chrome DevTools cover image

Performance Analysis with Chrome DevTools

When it comes to performance, developers often use Lighthouse or similar performance analysis tools. But when the target site has protection against bots, getting information is not that simple. Chrome Devtools can help you with your performance analysis....

How to Style Using SCSS in Nuxt cover image

How to Style Using SCSS in Nuxt

Introduction SASS makes working on large projects more organized. It allows you to use variables, nested rules, mixins, and functions. The preferred styling method in Nuxt is component file styling, and integrating SASS into your project can make your component file styling appear more understandable. How to Import SASS in Nuxt To add SASS after setting up your Nuxt application, we will first install SASS and sass-loader. Let's run either of these commands depending on our package manager. ` Component File Styling With SASS and sass-loader installed in our project, we can now write SCSS in our component file. Lets see an example: ` In the example above, all we need to specify is lang="scss" on the style tag, and we can now write scss in that component. Global File Import and Variables To import SCSS files that are global, like variables and mixins files, we need to install style-resources: ` Next, we can update our nuxt.config.js file by adding the module we just installed to the buildModules. ` Next, let's create a global variables.scss file in our assets/style folder. Add a single variable inside: ` Next, we need to import this file inside the nuxt.config file: ` Now we have the variables in our variables.scss available in all our components for use. Next, let's test it out by updating our button component. ` We have updated our button variant color to be our global SCSS variable ($primary and $white). Mixins Mixins in SASS are used to write styles that can be reused in other parts of the code. Let's create a sample mixin to center an item. ` Next, we need to import our mixin in Nuxt config: ` Now, let's update our button component with our mixin: ` Functions Functions in SASS are used to write complex operations or behaviours that can be reused in other parts of the code. Let's create a function to handle a media query for our application. ` This is a basic example of what a function can be used for. More complex cases, like calculating percentage, can also be done. Let's import our mixin in Nuxt config: ` Let's update our button component with our function: ` We have been able to add SASS to our Nuxt project, and also looked at some ways in which SASS can make our codebase look cleaner. I hope this article has been helpful to you. If you encounter any issues, you can reach out to me on Twitter or Github....

State Management with Apollo Client and Vue using Reactive Variable cover image

State Management with Apollo Client and Vue using Reactive Variable

State Management is an integral part of Software development with tools like VueX, Pinia which is like VueX 5, Redux, Context API, and others. In our example, we will be using Vue3 composition API, a bit of TypeScript. This article will assume that you already have a project setup with Apollo. State Managemnet Before we dive into what state management is and what it offers, lets understand few thing which are integral to it. What is State? State is a part of an application, such as user details, usernames, login information, and website themes(dark or light). In simple terms, state is like a warehouse that's contents you can access when you need to from wherever you are. What is State Management? State Management is just simply a design pattern to help synchronize the state of the application throughout all of the components in the application. This also prevents us from passing too many props accross the application. When to implement State Management: - When the application contains large number of components. - To prevent redundant data, knowing well some other components might need that data. - Prevent passing props across the application, making it messy. For more explainations, you can check the links below: - What does state-management even mean and why does it matter in Front End Web Development with frameworks like React or Vue? by Sean Grogg - What does state-management even mean and why does it matter in Front End Web Development with frameworks like React or Vue? by Robert Polevoi - State management by Tom Nolle How to implement State management? There are so many ways to do it. But in this discussion, we will be implementing it with Vue Apollo. Apollo Client It is the client for Vue Apollo. It helps to easily integrate GraphQL queries and mutation in your application which, in our case, is Vue. Reactive Variables This is a new feature from Apollo Client 3. > Reactive variables are a useful mechanism for representing local state outside of the Apollo Client cache. How to create a Reactive variable in Apollo? This is quite simple since Apollo client provides us with makeVar. ` What the above code means is we make use of makeVar to create a variable of any type be it boolean, number, array, or object. Also, by calling the variable that makeVar is assigned to without passing a parameter will only output its current value, but passing a parameter will update its value. You can learn more about makeVar here. Setup of the Project We will be creating a state for a counter that does increment, decrement, or reset. But first, let's set up our enviroment. Setting up the Reactive variable Lets create our reactive variable in ./variables/counts.js: ` Configuring the cache Lets also update our cache config to something like this: ` Creating a component Let's create ./components/Counter.vue component: ` Please note that you can always get the counts value even without the GraphQL query. All you need to do is call count() like the example about _Reactive variables_, and force a re-render using loading as a ref. Like this: ` loading ref to help re-render when there is a change so as to get the latest value of counts. The manner you will prefer depends on what you want to achieve. But I will go with the example with the query as it still preserves the GraphQL feel. Conclusion State Management with Apollo Client saves you the stress of installing VueX, or Redux (for the React users), as long as the application makes use of Apollo. In this quick training, we learned about state and why state management is important to building and maintaining applications. Further, we learned how to manage state by using a reactive variable in Apollo. If you need any help understanding how to use this training, or additional clarification, please feel free to reach out to me....

What is Accessibility and Why It Matters cover image

What is Accessibility and Why It Matters

Billions of people around the world use various web applications in their everyday lives. As web developers, we strive to build strong websites that can be used and enjoyed by everyone. But what is accessibility and why should we care about it?...

How to Set Up OAuth with a Stripe App cover image

How to Set Up OAuth with a Stripe App

Stripe Apps are a great way to extend Stripe dashboard functionality using third-party integrations. But when using these integrations, developers must prioritize security. The best way to do this is by using OAuth with the third-party product with which you would like to integrate. However, there are some constraints, and we cannot use cookies to set up a cookie based authentication front-end only. In this article, we would like to show you how to do it with a NestJS back-end. Stripe signatures The best way to secure your API is by making sure that every request comes from a verified Stripe App instance. The @stripe/ui-extension-sdk package provides a way to generate a signature on the front-end side. This signature is valid for 5 minutes, and you can send it as a header for every request you make. For this to work, you need to have @stripe/ui-extension-sdk installed in your repository. ` In order to properly validate this signature on your API, you will need some additional information to be sent in the request headers as well. That information is the Stripe user's ID, and the Stripe account's ID. We found that the best way is to implement a global context with this information. ` The above context stores the ExtensionContextValue that gets passed from the Stripe dashboard to the app when it opens in the view. For example, if you are on a payment detail page, the userContext will contain information about your Stripe user, while the environment will provide you access to the object that you are viewing. In the above example, that would be the payment's ID as the objectContext.id property. Let's set up the view with this global context. ` Now, we can set up a hook to provide a proper fetch method that always appends a Stripe signature, and the other required fields to the headers. useFetchWithCredentials hook In order to make our future job easier, we need to set up a hook that creates a proper wrapper around fetch. That wrapper will handle setting the headers for us. It needs to have access to our GlobalContext, so we can get the Stripe user's, and their account's, IDs. ` Let's set up a very basic component for demonstrating the use of the useFetchWithCredentials hook. This component will be the default route for our app's navigation wrapper. It is going to handle more later. But for now, let's just implement a basic use for our hook. The AUTH_INIT_URL constant will point at our back-end's /api/oauth/userinfo endpoint. Please note that, for this to work, you are going to need to install react-router-dom. ` As we can see from the above implementation, this component will be the initial component that gets rendered inside of the application. It will send out a request to determine if the user is logged in. If they are logged in, we are going to send them to a route that is the first page of our application. If they are not signed in, we are going to redirect them to our login page. This initial call, just as every other API call, must be verified and always have a Stripe signature. Let's visualise how routing looks like right now: ` Stripe secrets and the Stripe API In order to be able to use the Stripe NodeJS Api, you will need two secrets from Stripe. One is your Stripe account's API key, and the other one is your Stripe-app's secret. You need to set up your .env file as the following. ` Stripe API key You can find your Stripe API key at https://dashboard.stripe.com/apikeys, under the Standard keys section. The key you are looking for is called Secret key, and you need to reveal it by clicking the button that hides it. Stripe App Secret For this key, you are going to need to upload your stripe-app using the stripe apps upload command. Make sure that you set a development app ID in your app manifest (stripe-app.json). After you uploaded your app, visit https://dashboard.stripe.com/apps. Under My Apps, you should see your uploaded application. Open it and search for the Signing secret. Reveal it and copy it into your .env file. Stripe NodeJS API Please make sure you have installed the stripe nmp package for your server code. In this example series, we use NestJS as our framework for our API. We need the above two secret keys to be able to start up our Stripe API. ` NestJS VerifySignatureInterceptor implementation In NestJS, we can use interceptors to abstract away repetitive logic that needs to be done on multiple requests. In our case, we need to verify almost every API for a valid Stripe signature. We have access to the proper secret keys, and we have a Stripe NodeJS API set up. Let's create our VerifySignatureInterceptor. ` Every interceptor must implement the intercept() method. We extract the Request object from the execution context, and we get the headers that we previously set in our useFetchWithCredentials hook. We call our verifySignature function which will throw errors if the signature is invalid. We also pass the Logger instance, so we can determine when an error comes from this interceptor in our logs. Please be aware that there are several reasons signature verification can go wrong, like if we provide the wrong Stripe account keys or app secrets. In order for you to be able to easily debug these issues, proper logging is a must. That is why we set up a Logger instance in our interceptor. ` If the user_id, account_id, or the signature are missing, that could mean that the request came from outside a stripe application, or the useFetchWithCredentials hook was not used. We throw a BadRequestException that will result in the request sending back a status: 400 HTTP response. If the signature verification fails, that could mean that a not valid signature was used in the request, or that the API environment variables might have the wrong keys. Set up the userinfo endpoint Let's quickly set up our /api/oauth/userinfo endpoint. For that, we are going to create the OauthModule and the OauthController. ` In our controller, we decorate our getUserInfo() method, with the @Get() decorator, so we set up the route. We also decorate the method with the @UseInterceptors() decorator, where we pass our VerifySignatureInterceptor. ` This setup will enable us to call the /api/oauth/userinfo endpoint which will, in-turn, check if we have a valid signature present in the headers. If the request is invalid, it will throw a 400 Bad Request exception. If the signature is valid, for now, we will throw a 401 Unauthorized exception just to make our front-end navigate to the login page. The Login flow Just to keep this example simple, our login page will only have a button in the center that will start our login flow with our API. ` We need to create a state key, that can be validated before we fetch the token. This state key will first be sent to our third-party oauth client, and it will be returned to us when the authentication is finished. This key is passed securely and over https. Therefore, it can be a stringified object. While the key is not set, we disable the button. ` Pressing the Sign in button will call our API that will redirect us to our third-party login screen. When the login happens, it will redirect us to our API, where we can fetch a valid token and redirect again to the Stripe dashboard. Let's extend our environment variables. ` Now that we have every environment variable set up, let's implement our api/oauth/login and api/oauth/authorise endpoints in our OauthController. ` The login endpoint, if everything is correct, redirects us to the login page where the user should be able to log in. Make sure that if you oauth client needs to have configured redirect urls, you configure them. For example, for development, the http://localhost:3333/api/oauth/authorise endpoint should be in the allowed redirect url list. ` We validate everything to be sure that this endpoint was called from our third-party OAuth page. With the information available to us, we can fetch the access token and store it in the Stripe Secret Storage. In this example, we use axios in our bakc-end to send requests to our third-party API. ` We exchange our code returned from our OAuth client to a valid access token, and then store it in the Stripe Secret Store. That logic got extracted into a SecretService class, because the logic implemented in it can be reused later for other API calls. Please make sure you set up a NestJS module that exports this service. Stripe Secret Store Stripe's Secret Store API enables your app to securely store and retrieve strings that can be authentication credentials, tokens, etc. This API enables users to stay logged in to third party services even when they log out of their Stripe dashboard. Let's set up a service that handles access to the Secret Store on our back-end. ` Adding secrets As we can see above, the Secret Storage needs some preliminary setup, which we do in our SecretService. The StripeResource sets up the find, set, and delete methods on the Stripe Api, and interacts with the Secret Store. Let's implement the addSecret method, so we can actually store our returned token. ` With the above, we can finally store our token with which we can make authenticated requests. Getting secrets Let's implement the getSecret so we can retrieve secrets. The principles are the same. We will need the accountId, the userId, and the secret's name for it. ` Let's close the login flow, and implement the final version of the api/oauth/userinfo endpoint. ` Deleting secrets We want our users to have ability to log out from our third-party API as well. That can be achieved by deleting their access_token from the Secret store. ` The /api/oauth/logout endpoint is going to be a GET request, that will delete the token from the Secret Store. ` We can create a SignOutLink that will send the request to our back-end and navigates to the /login page. You can put this component into the footerContent property of your ContextView. ` And now we are ready with our authentication setup. When the user opens our app, it will call the /api/oauth/userinfo endpoint. Initially, it will return with a 401 error, and our front-end will navigate to the /login route. When the user presses the Sign in button, it will redirect them to the third-party OAuth page. After they log in, our back-end also redirects them back to their Stripe dashboars where the application will open. The app will call the /api/oauth/userinfo endpoint again. But this time, it will return an actual user information and it routes to the protected route. To help visualize the whole flow, you can also use the following sequence diagram for reference: Conclusion As you can see, there are many steps involved in setting up a proper OAuth flow. However, it's necessary to make it right, since this is the most critical part of the app. We hope blog post article will help you to set up some good foundations when implementing your own Stripe app....

12 Web Development Podcasts That Inform and Inspire cover image

12 Web Development Podcasts That Inform and Inspire

Podcasts can be a great source of entertainment and education but sometimes it is hard to know what to listen to. In this article, I will share with you my favorite podcasts to listen to that discuss the latest in web technologies and careers....

How to Manage Breakpoints using BreakpointObserver in Angular cover image

How to Manage Breakpoints using BreakpointObserver in Angular

Defining Breakpoints is important when you start working with Responsive Design and most of the time they're created using CSS code. For example: ` By default, the text size value will be 12px, and this value will be changed to 14px when the viewport gets changed to a smaller screen (a maximum width of 600px). That solution works. However, what about if you need to _listen_ for certain breakpoints to perform changes in your application? This may be needed to configure third-party components, processing events, or any other. Luckily, Angular comes with a handy solution for these scenarios: the BreakpointObserver. Which is a utility for checking the matching state of @media queries. In this post, we will build a sample application to add the ability to configure certain breakpoints, and being able to _listen_ to them. Project Setup Prerequisites You'll need to have installed the following tools in your local environment: - Node.js. Preferably the latest LTS version. - A package manager. You can use either NPM or Yarn. This tutorial will use NPM. Creating the Angular Project Let's start creating a project from scratch using the Angular CLI tool. ` This command will initialize a base project using some configuration options: - --routing. It will create a routing module. - --prefix corp. It defines a prefix to be applied to the selectors for created components(corp in this case). The default value is app. - --style scss. The file extension for the styling files. - --skip-tests. it avoids the generations of the .spec.ts files, which are used for testing Adding Angular Material and Angular CDK Before creating the breakpoints, let's add the Angular Material components, which will install the Angular CDK library under the hood. ` Creating the Home Component We can create a brand new component to handle a couple of views to be updated while the breakpoints are changing. We can do that using the ng generate command. ` Pay attention to the output of the previous command since it will show you the auto-generated files. Update the Routing Configuration Remember we used the flag --routing while creating the project? That parameter has created the main routing configuration file for the application: app-routing.module.ts. Let's update it to be able to render the home component by default. ` Update the App Component template Remove all code except the router-outlet placeholder: ` This will allow rendering the home component by default once the routing configuration is running. Using the BreakpointObserver The application has the Angular CDK installed already, which has a layout package with some utilities to build responsive UIs that _react_ to screen-size changes. Let's update the HomeComponent, and inject the BreakpointObserver as follows. ` Once the BreakpointObserver is injected, we'll be able to evaluate media queries to determine the current screen size, and perform changes accordingly. Then, a breakpoint$ variable references an _observable_ object after a call to the observe method. The observe method gets an observable of results for the given queries, and can be used along with predetermined values defined on Breakpoints as a constant. Also, it's possible to use custom breakpoints such as (min-width: 500px). Please refer to the documentation to find more details about this. Next, you may need to _subscribe_ to the breakpoint$ observable to see the emitted values after matching the given queries. Again, let's update the home.component.ts file to do that. ` In the above code, the ngOnInit method is used to perform a _subscription_ to the breakpoint$ observable and the method breakpointChanged will be invoked every time a breakpoint match occurs. As you may note, the breakpointChanged method verifies what Breakpoint value has a match through isMatched method. In that way, the current component can perform changes after a match happened (in this case, it just updates the value for the currentBreakpoint attribute). Using Breakpoint values on the Template Now, we can set a custom template in the home.component.html file and be able to render a square according to the currentBreakpoint value. ` The previous template will render the current media query value at the top along with a rectangle according to the size: Large, Medium, Small or Custom. Live Demo and Source Code Want to play around with this code? Just open the Stackblitz editor or the preview mode in fullscreen. Find the complete angular project in this GitHub repository: breakpointobserver-example-angular. Do not forget to give it a star ⭐️ and play around with the code. Feel free to reach out on Twitter if you have any questions. Follow me on GitHub to see more about my work....

What's New in React 18? cover image

What's New in React 18?

Discover the new features released in React 18....

How to Build a Slideshow App Using Swiper and Angular cover image

How to Build a Slideshow App Using Swiper and Angular

Luis Aviles...