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.
Nuxt 3 Demo App with Prerender and SSR
Introduction The quest for an optimal web application involves numerous factors, such as performance, user experience, and search engine optimization (SEO). Nuxt 3 provides excellent features out-of-the-box that can help you tackle these aspects efficiently. This article will guide you in creating a Nuxt 3 application using Server Side Rendering (SSR) and pre-rendering capabilities. We'll craft an application that offers a seamless user experience, superior performance, and improved SEO. Server Side Rendering in Nuxt 3 Enhancing User Experience and SEO with SSR In the world of web development, Server Side Rendering (SSR) has gained significant traction. It refers to the server rendering the webpage upon each request rather than the client. With SSR, your web page arrives fully formed at the client's doorstep, reducing the time for the first painting. The advantage of SSR extends beyond just performance and user experience. It's also a darling of search engine crawlers, which find it easier to index your website with fully formed page content at the time of their crawl. In simple terms, it's like providing a tour guide to lead the search engine around your website, ensuring they get all the spots! The Power of SSR in Nuxt 3 Nuxt 3 has built-in support for SSR by default. It allows you to optimize your application by loading the data before rendering the page. To take advantage of SSR, you simply build your application as you usually would. In this case, using the fetch() method to load some. ` In this example, the fetchData function fetches the data before rendering the page. The data then gets displayed within the tag. Sidenote, if you wanted to disable SSR in your Nuxt application, you would do so in your nuxt.config.ts file: `` More details on how this works can be found in the rendering modes section in the official Nuxt 3 documentation. Pre-rendering in Nuxt 3 Amplifying Application Performance with Pre-rendering While SSR has its advantages, another superhero in our story is pre-rendering. Pre-rendering refers to the process of generating the static HTML pages of a site in advance. It's like preparing a feast before the guests arrive so you can serve them promptly. Like SSR, pre-rendering enhances SEO, as search engines can index fully rendered pages. Especially for content-heavy applications, pre-rendering can give a turbo boost to performance, leading to better user engagement and retention. Leverage Pre-rendering with Nuxt 3 Nuxt 3 supports SSR and Static Site Generation (SSG), including pre-rendering. To enable prerendering, you need to export your routes in nuxt.config.ts: ` These routes will be pre-rendered during the build phase, allowing for swift navigation. Let's update our application to pre-render the users' list: ` In the nuxt.config.ts, include the users' route for pre-rendering: ` Going beyond with Nuxt 3 While SSR and pre-rendering are significant for performance and SEO, Nuxt 3 offers more advanced features like hot module replacement, Vue 3 integration, improved error handling, and more. Nuxt 3 also has different kinds of rendering modes for different applications; in our SSR case, we used the default Universal rendering mode. Leveraging these features allows you to develop robust, high-performance, and user-friendly applications. Conclusion In this article, we delved into the concepts of SSR and pre-rendering in Nuxt 3. We explored how these techniques contribute to enhancing performance, user experience, and SEO. You can create exceptional web applications by integrating Vue 3's capabilities with Nuxt 3's robust features. A well-structured, performant, and SEO-friendly application not only attract users but also retains them. Embrace the power of Nuxt 3 and Vue 3 in your development journey. Happy coding!...
Aug 2, 2023
3 mins
Avoiding Burnout for Remote Teams: A Software Engineer's Guide
Pull up a chair, my fellow coders, team leads, and everyone working from a desk in their pajamas. Let's talk about something that's been buzzing around like an annoying fly we've been trying to swat: burnout. Yeah, we all know what I'm talking about. The long hours, the lack of sunlight (my plant is getting a better tan than me - just kidding, I don't have a plant), the never-ending to-do list, and the work-life balance hanging by a thread. If you're nodding along, then you're in the right place. In this piece, we'll navigate the maze of remote work and uncover ways to keep that nasty burnout at bay. And I promise there won't be any code debugging here, just some light-hearted yet meaningful advice coming your way. Ready to dive in? Awesome, let's get started! Setting Clear Boundaries Working from home has its perks. No commute, comfortable attire, and flexible hours. But let's get real. The downside is that work can become a 24/7 gig if you aren't careful. My living room turned office, turned dining room, makes me feel like I'm always on duty. So how do we fight this? We do what we do best. We set some boundaries. Defining a workspace is essential, even if it's just a corner of the room. This physical boundary tells your brain "I'm in work mode now." Trust me; your brain will thank you for it. Next comes the schedule. I'm not talking about planning every minute of your day, but having a structured work schedule is crucial. Have a defined start time, breaks, and, most importantly, a shutdown time. And let me tell you, this shutdown time is non-negotiable. Like the last slice of pizza at a party, you don't touch it, and I've got to admit, I struggle with it, but I am working on it. Asynchronous Communication With a team spread across the globe, synchronicity is a luxury we can't afford. We've got people working from their night to match our day, and that's just not fair. What can we do about this? Embrace asynchronous communication. Let's do away with the pressure of immediate responses. People can respond in their time, respecting their work hours. And let's be honest, most of our communication doesn't need instant answers. Time differences are not villains but part of our remote work reality. Results Over Hours A common misconception about remote work is that "the more hours I work, the more productive I am." Well, that's as far from the truth as I am from my next vacation. The focus should be on results, not hours clocked in. Set realistic goals and trust your team to manage their time effectively. This trust is essential for a remote team. After all, we don't have someone peeping over our shoulder, making sure we're working. Or at least I hope not! Mental Health Support Mental health: the elephant in the room. Why do we tip-toe around it? Stress, anxiety, and burnout are real, and they're here. It's high time we address them. Resources like Employee Assistance Programs, mindfulness apps, and virtual fitness classes are excellent support systems. But they're not magic potions. They need regular utilization, and we need to make our team comfortable with seeking help. Let's make it our strength, not a weakness. Regular Breaks Do you know what's the quickest way to burnout? Working without breaks. I know we've all been guilty of it at some point. But let's change that. Taking breaks is not a luxury; it's a necessity. Short walks, quick exercises, or just stepping away from the screen can do wonders. I even tried the Pomodoro technique, and it's a game-changer. Another thing you could do is schedule lunch breaks in your calendar so your colleagues know when not to try to reach you. You can additionally set your focus times in your calendar so that you can maximize your time in flow state without interruptions. Prioritize Effective Communication Communication. It can make or break a remote team. Without physical cues, messages can be easily misinterpreted. Open, transparent, and empathetic communication is the solution. Regular check-ins and feedback sessions also help keep things running smoothly. After all, we're a team, and teams need to talk! Training and Development Boredom is a silent killer in remote work. And the best defense is learning. Offering training and development opportunities enhances skills and breaks the monotony. Who would want to learn something other than a new language or skill? Plus, it aligns with our long-term career goals. It's a win-win situation. Time Off I can't stress this enough. Time off is essential! We need to recharge, relax, and rejuvenate. Encourage your team to disconnect during their time off fully. Trust me; the world will only end if we check our emails for a few days. I tried it, and I'm still here! Empathy and Flexibility Last but not least, empathy and flexibility. Everyone's situation is different. Let's show understanding for those juggling childcare, living in different time zones, or dealing with personal issues. Let's be leaders who are empathetic and flexible. Conclusion In the world of remote work, prevention is better than cure. And the prevention of burnout comes with boundary setting, asynchronous communication, focus on results, mental health support, regular breaks, effective communication, continuous learning, time off, and empathy. With these in place, we can navigate the remote work culture while keeping our sanity intact. So let's dive in, shall we?...
Jul 31, 2023
4 mins
Layouts & Theming in Vuetify 3
Introduction Do you want to avoid tinkering with CSS to get your website looking just right? Branding is everything in today's digital landscape. With Vuetify 3's customizable theming options, you can create web projects that perfectly reflect your unique branding, and visual identity. Additionally, you can reduce the duplicated code by creating layouts representing your application's different page structures. In a previous article introducing Vuetify 3 with Vue 3, we created an application that allowed us to add, display, and delete jokes. If you'd like to follow along with this article, please clone the GitHub repository. ` In this article, we'll go over how you can create layouts in Vuetify 3 to allow you to reuse the same layout for pages that share the same structure. We will also go over how you can customize the look and feel of your application to match your brand's visual identity through the powerful theming tools that Vuetify 3 offers us. Layouts in Vuetify 3 What are layouts, and how are they useful? In web development, layouts are akin to blueprints for the structure of your web pages. They provide a consistent and reusable frame for the different pages of an application. A well-designed layout can improve the user experience by providing familiarity and predictability as the user navigates through other parts of your application. Layouts are particularly helpful in reducing code duplication. Instead of defining the same structure for each page—headers, footers, and navigation menus, you define them once in a layout, and then apply that layout to any page that uses the same structure. This speeds up development, and makes your code easier to maintain. Using Layouts in Vuetify 3 Creating a layout in Vuetify 3 is as simple as creating a new Vue component. This component will include the common elements shared across multiple pages like headers, footers, and navigation bars. Here is an example of a basic layout: ` This layout has a header, a navigation drawer, and a footer. The component is where the content of the specific pages will be injected. Building a layout for our application Let's create a layout for our application. We'll have a top navigation bar and a footer. Inside the layouts directory, create a new file named Default.vue and add the following code: ` Additionally, in order for us to use our layout, we will need to modify our router/index.ts file to use the Default.vue component: ` This will make sure that our respective pages use the Default.vue layout that we created. The contents of the pages will appear in place of in the layout. It is also worth noting that you can create, and nest as many layouts as you want. Theming in Vuetify 3 Themes allow you to customize your application's default colors, surfaces, and more. If your brand has specific colors and styling, you can theme your Vuetify application to resemble your brand through theming better. Additionally, Vuetify 3 allows you to modify your theme in real-time programmatically. [Vuetify 3] also comes with light and dark themes pre-installed. Theming API Vuetify 3 offers us 2 main APIs for working with themes: - useTheme is a composable that allows us to get information about the current theme and will enable us to modify the existing theme. - v-theme-provider is used in the section of your Vue files to modify the theme of all of its children. Updating the theme of our application Updating the theme of our application is straightforward with Vuetify 3. Let's customize our application's primary and secondary colors. In the vuetify.ts file, modify the themes section to contain the following styles: ` In this example, we're defining a custom 'light' theme. If you want to use a dark theme, or any other named theme, you can add those as additional properties within the themes object. For example: ` And... That's it! By changing the various config options in the vuetify.ts file, you can modify how your application looks and feels to match your brand. If you'd like to learn more about themes and all the options you can provide, please check out the official Vuetify documentation. Conclusion In this article, we've gone through the concepts of layouts and theming in Vuetify 3. We've seen how layouts can reduce code duplication, and provide consistency across your application. We've looked at how Vuetify's theming features allow you to customize your application to match your brand's visual identity. Understanding and utilizing these features effectively can significantly enhance the development experience and the end user's interaction with your application. Remember, a well-structured and visually appealing application not only attracts users, but also retains them. Happy coding!...
May 19, 2023
4 mins
Getting Started with Vuetify in Vue 3
If you're here to learn about Vuetify and how to use it with Vue 3, you've come to the right place. In this article, we'll introduce Vuetify, a Material Design component framework for Vue.js, and walk you through setting it up in a Vue 3 project. We will also build a simple web app that allows us to create and vue jokes. Oh, sorry, view* jokes! What is Vuetify? Vuetify is a VueJS Material Design component framework. That is to say that Vuetify provides us with prebuilt components and features (e.g. internationalization, tree shaking, theming, etc.) to help us build Vue applications faster. Additionally, Vuetify components have built-in standard functionality, such as validation in form inputs, or various disabled states in buttons. You can check out a full list of components supported by Vuetify on their official documentation website. Setting things up Before we get started, you will need the following on your machine: - NodeJS installed - A NodeJS package manager e.g. yarn or npm installed - Intermediate knowledge of Vue 3.x with the composition API If you’d like to follow along, feel free to clone the github repository for this article. ` Installing Vuetify We will be using yarn to install and setup Vuetify 3 (the version that supports Vue 3) in this case. First, let's create a new Vuetify project. You can do this by running the following command in your terminal or command prompt: ` This will create a new Vuetify project. For our jokes app, we will use the Essentials (Vuetify, VueRouter, Pinia) preset when creating our app. We will also be using TypeScript for our app, but this is not necessary. Since VueJS allows us to build incrementally, if you would like to instead add Vuetify to an existing project, you can use the manual steps provided by the Vuetify team. Testing our application Once we have installed and configured our application, cd into the project's directly, and run the app using the following command: ` Visit localhost:3000/ to see your app in action. Vuetify project folder structure Our Vuetify project is generally structured as follows: - public - Contains static assets that do not need preprocessing eg. our application favicon - src - Contains our VueJS source code. We'll mostly be working here. - assets - Assets that need to be preprocessed eg. our images that may need to be compressed when building for production - components - layouts - Layouts - plugins - Everything gets wired up here (registration of our app as well as vuetify, our router & pinia) - router - Vue router-related functionality - store - Pinia store - styles - views - our web app's "pages" Worth noting before building It is worth noting that all components in Vuetify start with a v- for example: - v-form is a form - v-btn is a button component - v-text-field is an input field and so on and so forth. When creating your own components, it is recommended to use a different naming approach so that it is easier to know which components are Vuetify components, and which ones are your components. Building our Vuetify application We will build a web app that allows us to add, view and delete jokes. Here are the steps we will take to build our app: - Delete unnecessary boilerplate from generated Vuetify app - Add a joke pinia store - we'll be using this to store our jokes globally using Pinia - Create our joke components - components/jokes/CreateJokeForm.vue - the form that allows us to add jokes - components/jokes/JokeList.vue - Lists our jokes out. - Add our components to our Home.vue to view them in our home page Setting up the jokes pinia store In the src/store/ directory, create a new file called joke.ts that will serve as our Pinia store for storing our jokes. The file content for this will be as follows: ` This code defines a special storage space called a "store" for jokes in our Vue.js app. This store keeps track of all the jokes we've added through our app's form. Each joke has an ID, title, and punchline. The addJoke function in the store is used to add a new joke to the store when a user submits the form. The removeJoke function is used to delete a joke from the store when a user clicks the delete button. By using this store, we can keep track of all the jokes that have been added through the app, and we can easily add or remove jokes without having to manage the list ourselves. Creating the joke components CreateJokeForm.vue Create a file in src/components/jokes/ called CreateJokeForm.vue. This file defines a Vue.js component that displays a form for adding new jokes. The file should have the following contents: Template section ` In the template section, we define a form using the v-form component from Vuetify. We bind the form's submit event to the submitJoke method, which will be called when the form is submitted. Inside the form, we have two text fields" one for the joke title, and one for the punchline. These text fields are implemented using the v-text-field component from Vuetify. The label prop sets the label for each text field, and the outlined prop creates an outlined style for each text field. The required prop sets the fields as required, meaning that they must be filled in before the form can be submitted. Finally, we have a submit button implemented using the v-btn component from Vuetify. The button is disabled until both the title and punchline fields are filled in, which is accomplished using the :disabled prop with a computed property that checks if both fields are empty. Script section ` In the script section, we import some functions and types from Vue.js and the joke store. We then define a jokeStore variable that holds the instance of the useJokeStore function from the joke store. We also define two refs, jokeTitle, and jokePunchline, which hold the values of the form's title and punchline fields, respectively. We then define a computed property, joke, which creates a new Joke object using the jokeTitle and jokePunchline refs, as well as the length of the jokes array in the jokeStore to set the id property. Finally, we define a submitJoke function that calls the addJoke method from the jokeStore to add the new joke object to the store. We also reset the jokeTitle and jokePunchline refs to empty strings. JokeList.vue Template section This one looks bulky. But in essence, all we are doing is displaying a list of jokes when they are found, and a message that lets us know that there are no jokes if we have none that have been added. ` In the template section, we define a v-card component, which is a container component used to group related content in Vuetify. The card contains a title, which includes an excited emoticon icon from the mdi-emoticon-excited-outline icon set from Material Design Icons, displayed using the v-icon component. The jokes are displayed in a v-list, which is a component used to display lists in Vuetify. Each joke is represented by a v-list-item containing a title and subtitle. The v-row and v-col components from Vuetify are used to divide each list item into two columns: one column for the joke title and punchline, and another column for the delete button. The delete button is implemented using the v-btn component from Vuetify. The button is red, and outlined using the color="error" and variant="outlined" props, respectively. The @click event is used to call the deleteJoke function when the button is clicked. If there are no jokes in the jokeStore, the component displays an v-alert component with a message to add some jokes. Script section ` In the script section, we import some functions and types from the joke store. We then define a jokeStore variable that holds the instance of the useJokeStore function from the joke store. We also define a deleteJoke function that takes a joke object as an argument and calls the removeJoke method from the jokeStore to remove the joke from the store. This component is called JokeList.vue and displays a list of jokes using Vuetify components like v-card, v-list, v-list-item, v-row, v-col, and v-btn. The component includes a deleteJoke function to remove a joke from the jokeStore as well. Wiring it up To display our form as well as list of jokes, we will go to the src/views/Home.vue file and change its contents to the following: ` The Home.vue file defines a Vue.js view that displays the home page of our app. The view contains a v-container component, which is a layout component used to provide a responsive grid system for our app. Inside the v-container, we have a v-row component, which is used to create a horizontal row of content. The v-row contains two v-col components, each representing a column of content. The cols prop specifies that each column should take up 12 columns on small screens (i.e. the entire row width), while on medium screens, each column should take up 6 columns (i.e. half the row width). The first v-col contains the CreateJokeForm component, which displays a form for adding new jokes. The second v-col contains the JokeList component, which is used to display a list of jokes that have been added through the form. In the script section of the file, we import the CreateJokeForm and JokeList components, and register them as components for use in the template. This view provides a simple and responsive layout for our app's home page, with the CreateJokeForm and JokeList components displayed side by side on medium screens and stacked on small screens. Bonus: Layouts & Theming Layouts Even though we had no need to adjust our layouts in our current jokes application, layouts are an important concept in Vuetify. They allow us to pre-define reusable layouts for our applications. These could include having a different layout for when users are logged in, and when they are logged out or layouts for different types of users. In our application, we used the default Layout (src/layouts/default/Default.vue) but Vuetify offers us the flexibility to build different layouts for the different domains in our applications. Vuetify also supports nested layouts. You can learn more about layouts in Vuetify in the official Vuetify documentation. Theming If you have specific brand needs for your application. Vuetify has a built-in theming system that allows you to customize the look and feel of your application. You can learn more about theming in the official Vuetify theming documentation. Conclusion In this article, we introduced Vuetify, and covered how to set it up with Vue 3. We built a VueJS app that allows us to add and manage jokes. We also discussed how to use various Vuetify components to compose our UI, from v-form for declaring forms to v-row for creating a row/column layout, and v-list for displaying a list of items among others. With this knowledge, you can start using Vuetify in your Vue 3 projects and create stunning user interfaces. Also, if you'd like to start your own VueJS project but need help with how to structure it or would like to skip the tedious setup steps of setting up a VueJS project, you can use the Vue 3 Starter.dev kit to skip the boilerplate and start building! Next steps for learning Vuetify and Vue 3 development Now that you have an understanding of Vuetify, it's time to dive deeper into its features, and explore more advanced use cases. To continue your learning journey, consider the following resources: 1. Official Vuetify documentation: The Vuetify documentation is an excellent resource for learning about all the features and components Vuetify offers. 2. Vue 3 documentation: To get the most out of Vuetify, it's essential to have a solid understanding of Vue 3. Read the official Vue 3 documentation and practice building Vue applications. Happy coding, and have fun exploring the world of Vuetify and Vue 3!...
Apr 14, 2023
8 mins
Improving the Performance of Vue 3 Applications Using v-memo and KeepAlive
Optimize your Vue.js application with v-memo for memoization and the KeepAlive component for caching and improve your site users experience....
Feb 24, 2023
4 mins
Converting Your Vue 2 Mixins into Composables Using the Composition API
Introduction There are two main ways to add additional functionality to our Vue components: mixins and composables. Adding mixins is similar to adding properties through the options API because you can add them by creating and "injecting" the properties into your Vue components. However, this comes with a couple of problems, the primary one being that mixins can lead to messy code and conflicting names. This is because they dump their properties into the component. With the composition API that was introduced in Vue 3, we can mitigate the problems we just mentioned by using composables. The Vue team created composables as a better alternative to mixins that allow for greater code reuse and structure. Additionally, they are designed specifically for each component, and don't cause any naming issues. We'll see more of this later on. In this article, we'll show you how to take your mixins and turn them into composables for even more functionality and ease of maintenance. The Structure of a Mixin Now, before we say goodbye to mixins and embrace composables, we need to understand the main differences between the two. In a way, a mixin is like a bag of magic tricks you can easily add to your components to do their magic. However, having all these tricks in her one backpack can make it challenging to keep track of what's happening, especially if multiple components use the same mixin. For example; if there was a data property called message in our mixin, and a property by the same name (message) in our component, the mixin message would clash with our component's message (which would have been declared in the data section of our component). We will be going over composables next. But before we do, here's an example of a mixin: ` In this example, the mixin contains a data function that returns an object with a message property, as well as a printMessage method that logs the given message to the console. To use this mixin in a component, the component would need to import the mixin, and add it to its mixins option: ` Creating the Composable Composables are a new feature that was added within the Vue 3 composition API. Composables are also called composition functions. They allow us to add functionality to components in a cleaner, more maintainable way. Instead of merging properties and methods directly into the component like in a mixin, composables are explicitly tailored to the component, and return a value or a set of reactive properties. What this means is that with composables, you can group all the functionality that is related together (rather than in separate data, computed, and methods sections). Again, you also don't have name collisions anymore because each call to a composable will give you an object that is not tied to your existing component. That means that you can resolve any naming conflicts at development time rather than breaking your application because of the same thing happening at runtime as is the case with mixins. Here is a simple composable that achieves the same result as the mixin we had created earlier. ` Here's how the composable can be used in a .vue file component: ` With this setup, the component will access the reactive message property and the printMessage method returned by the composable. Notice that composables allow us to add functionality to components more intuitively and easier to understand without the clutter of a mixin's structure. In general, the naming convention for composables is useX, where X is the domain our composable is meant to represent. In this case, since our functionality is around our message, our composable is called useMessage. Conclusion In this article, we've explored how to convert Vue 2 mixins to Composition API composables. We started by understanding the structure of a simple Vue 2 mixin, which can make components challenging to maintain due to how they merge properties and methods directly into the component. Next, we looked at how to create a composable in Vue.js 3's Composition API, which allows us to add functionality to cleaner and more maintainable components. Composables are explicitly tailored to the component and return a value or a set of reactive properties, making them easier to understand and use in components. With this understanding of mixins and composables, developers can now confidently convert their Vue 2 mixins to Vue 3 composables, taking advantage of the new and improved functionality offered by the Composition API. By doing so, developers can create more manageable components to maintain, test, and debug, resulting in a better user experience for their applications. Also, if you are looking to start a new Vue JS project and are not sure of how to structure your project, feel free to check out our Vue JS starter.dev GitHub showcases which showcase (no kidding) a mini-GitHub clone application built using Vue in different ways (eg. using Nuxt, Quasar, Vite, etc). Alternatively, if you are simply looking to start a new project without worrying about all the config required to do so, you can check out the Vue JS starter kit instead. Either way, thanks for stopping by!...
Feb 17, 2023
4 mins
How to Create Browser Extensions Using Quasar and Vue 3
Browser extensions allow us to extend the functionality of our browsers. Some extensions provide us with additional data about the web pages we visit for example: - Wappalyzer - Provides us with information on what technology was used to build a website - Similar web - Provides web page traffic and ranking data Others replace your default home screen, for example: momentum while others modify the contents of web pages. What we'll build In this article, we'll be creating a chrome extension using Vue 3 and Quasar. Our extension will change the font size of text on any page we visit. This could, for example, be useful for accessibility. How browser extensions [generally] work - You create your project with a manifest.json file. This contains all relevant metadata for your extension. - Write the scripts that will run when your extension is installed, and setup where those scripts will run through the manifest.json file created in the first step. Creating an extension using quasar It is worth noting that Quasar BEX has been tested and developed on Chrome and Firefox, but all Chromium based browsers should work the same. Create a new quasar project If you haven't already, install the quasar-cli and create a mew quasar project by running: ` - Select App with QUasar CLI - Enter the name of your project. Quasar will create a new directory and initialize the project in that directory. > If you're creating the project in a directory you have already created, then you can set the directory name as . - Pick Quasar V2 with Vue 3 - Pick either Typescript or Javascript. In this example, we'll be using Typescript, but you should be able to follow along with Javascript. - Initialize your project with Vite. - Complete the rest of the prompts with the defaults or alter as needed. Context around extensions in Quasar Extensions in Quasar can be created by setting the Quasar application type to BEX. BEX stands for Browser Extension, and is a set of utility functions provided to us by Quasar. Quasar can handle the various places where our extensions can live: - New tab - Dev tools, Options & Popup - Web Page - This allows us to inject our Quasar application into other web pages. It is the most powerful of the three. Add Quasar BEX mode In order to build a BEX, we first need to add the BEX mode to our Quasar project: ` If you'd like to jump straight into development, you can run the following command instead to add BEX mode automatically and add the src-bex/ directory to your project if it is missing: ` Select Manifest Version 3 when creating the application. As of this article's writing, this will only work in Chrome. You can check this out to understand the anatomy of the src-bex directory. Configuring BEX The most important config file for your BEX is /src-bex/manifest.json. This is the same manifest file we talked about when we were discussing how browser extensions work. It is recommended that you read up on the structure of this file before proceeding. Here, you will find details on how to change the icons of your extension as well as other relevant options. The TL;DR of what we need to know for this project is that there are 2 scripts behind every BEX: - Background Script - runs in the context of the BEX itself and can listen to all available browser extension events. There will only ever be one instance of each background script per BEX. - Content Script - runs in the context of the web page. There will be a new content script instance per tab running the extension. Further documentation on configuring your bex can be found in the official Quasar documentation. Testing your extension Open Google Chrome and go to chrome://extensions. Ensure you have Developer mode checked. Click on "Load unpacked extension" to install our extension. Select the directory that contains your manifest.json, which in this case would be the root directory of your project's build directory, and load it. For Chrome, that would be /dist/bex. Once you have loaded the extension, you can use the extensions menu on the top right (in Chrome) to access your extension. This should launch a Quasar application. If you wish to update your extension, you'll need to click the reload extension button in Chrome. Adding the functionality In order to make this happen, we'll simply need to add our custom font-modification CSS to our extension in src-bex/assets/content.css. This file allows us to override the CSS of any web page we visit. Below is the CSS: ` If you refresh your extension now and visit any web page, you'll find that the font-size. Bonus If you wanted to replace the page that appears when you open a new tab in Chrome, all you'd need to add is the following to your src/my-content-script.ts: ` Conclusion There is so much more we could do with extensions, like injecting JavaScript that alters the pages we visit to building ad-blockers. This article is meant to be an introduction to the concepts around creating browser extensions. If you'd like to learn more about creating browser extensions, you can check out the chrome extension documentation and Quasar's BEX documentation....
Dec 21, 2022
5 mins
How to Retry Failed Steps in GitHub Action Workflows
Sometimes things can go wrong in your GitHub Action workflow step(s), and you may want to retry them. In this article, we'll cover two methods for doing this! Pre-requisites - Git This should be installed in your path. - GitHub account: We'll need this to use GitHub Actions. Initial setup In order to follow along, here are the steps you can take to setup your GitHub Actions workflow: Initialize your git repository In your terminal, run git init to create an empty git repository or skip this step if you already have an existing git repository. Create a workflow file GitHub workflow files are usually .yaml/.yml files that contain a series of jobs and steps to be executed by GitHub Actions. These files often reside in .github/workflows. If the directories do not exist, go ahead and create them. Create a file retry.yml in .github/workflows. For now, the file can contain the following: ` Testing your workflow You can test your GitHub Action workflow by pushing your changes to GitHub and going to the actions tab of the repository. You can also choose to test locally using Act. Retrying failed steps Approach 1: Using the retry-step action By using the retry-step action, we can retry any failed shell commands. If our step or series of steps are shell commands, we can use the retry-step action to retry them. > If, however, you'd like to try retry a step that is using another action, then the retry-step action will NOT work for you. In that case, you may want to try the alternative steps mentioned below. Modify your action file to contain the following: ` Approach 2: Duplicate steps If you are trying to retry steps that use other actions, the retry-step action may not get the job done. In this case, you can still retry steps by retrying steps conditionally, depending on whether or not a step failed. GitHub provides us with two main additional attributes in our steps: - continue-on-error - Setting this to true means that the even if the current step fails, the job will continue on to the next one (by default failure stops a job's running). - steps.{id}.outcome - where {id} is an id you add to the steps you want to retry. This can be used to tell whether a step failed or not, potential values include 'failure' and 'success'. - if - allows us to conditionally run a step ` Bonus: Retrying multiple steps If you want to retry multiple steps at once, then you can use composite actions to group the steps you want to retry, and then use the duplicate steps approach mentioned above. Conclusion How do you decide which approach to use? - If you are retrying a step that is only shell commands, then you can use the retry step action. - If you are retrying a step that needs to use another action, then you can use duplication of steps with conditional running to manually retry the steps....
Nov 29, 2022
3 mins
Using PartyTown to Improve the Performance of VueJS Applications
PartyTown is a JavaScript library that improves the performance of web applications by delegating the running of resource intensive tasks to web workers. This frees up the main thread to only run the code that we write....
Jul 14, 2022
4 mins
Vue 3 Composition API: How to Omit `.value` in refs
A technical article that expounds on how we can omit using .value when accessing reactive variables declared as refs....
May 13, 2022
6 mins
Let's innovate together!
We're ready to be your trusted technical partners in your digital innovation journey.
Whether it's modernization or custom software solutions, our team of experts can guide you through best practices and how to build scalable, performant software that lasts.