Skip to content

Nuxt.js for Complete Beginners

This article was written over 18 months ago and may contain information that is out of date. Some content may be relevant but please refer to the relevant official documentation or available resources for the latest information.

The Vuejs Amsterdam online conference was held at the end of February in 2021. It brought together Vue.js enthusiasts and community members from around the world. Many interesting topics were presented and covered. The focus, of course, was on Vue.js 3. In addition, the creators of Nuxt.js had the opportunity to showcase it from the current standpoint in development, to their intentions for it down the track. They even demonstrated a pre-alpha version of Nuxt.js 3, that’s based on Vue.js 3.

This article will start by briefly covering general Nuxt.js concepts, creating a new Nuxt.js app using the create-nuxt-app CLI, and finally, going through the different files and folders that Nuxt.js auto-generates for us.

Let’s start!

Nuxt.js Concepts

Nuxt.js is a web development framework that builds on top of the Vue.js framework. It allows you to use your Vue.js skills to build a more confident, structured, SEO friendly website purely in Vue.js.

Remember when you had to mess with the Vue.js SSR module and the Vue Meta module to build a SEO friendly website? On top of that, you had to install and use Vuex and Vue Router too!

Well, Nuxt.js takes care of that! No more chaotic setup and scaffolding to start a new Vue.js app. With the help of the create-nuxt-app CLI, you can scaffold a Nuxt.js app in no time.

What’s remarkable about Nuxt.js is its capacity to enforce convention over configuration. This means, you write less configuration files by sticking to a specific directory structure that makes Nuxt.js happy and saves you a ton of time!

Apps supported by Nuxt.js

Nuxt.js supports building a variety of web apps, including the following:

Server-Side Rendering (SSR) SSR apps are also known as Universal Apps. The app gets rendered on the server-side before it is sent to the client-side, and is displayed in the browser. This is the best option when working on an SEO friendly website written in Vue.js.

You can read the full documentation for the SSR apps here: SSR Apps

Single Page Apps (SPA) This is what you’ve been doing so far with Vue.js. The app is compiled into a few JS and CSS files. When the user requests the app, the files are downloaded to the client-side, and the Vue.js engine takes over rendering and displaying the app.

Static Site Generation (SSG) Nuxt.js can pre-render your app at build time. This means the entire app will be converted to simple static HTML files that can be hosted and served over a Content Delivery Network (CDN). The SSG option makes an app a legal JAMStack app.

You can read the full documentation for the Static Site Generation here: Static Site Generation.

File System Routing

Nuxt.js automatically generates all the Vue.js Routes in your app based on the folder structure inside the pages folder.

For example, consider having this folder structure:

pages/
  --| user/
  -----| index.vue
  --| index.vue

Nuxt.js automatically generates the following route configuration:

router: {
  routes: [
    {
      name: 'index',
      path: '/',
      component: 'pages/index.vue'
    },
    {
      name: 'user',
      path: '/user',
      component: 'pages/user/index.vue'
    },
  ]
}

You can read about File System Routing here: File System Routing.

Data Fetching

Inside a Nuxt.js app, you can still use the old techniques you kmow when developing Vue.js apps. However, we have a new player here! Server-side rendering. Nuxt.js provides a new set of data-hooks that you can implement so that Nuxt.js can prefetch data when generating the app at the server-side.

Here are two data-hooks offered by Nuxt.js:

fetch() hook This hook was introduced with Nuxt.js 2.12+ release. It can be used inside Vue.js components stored in the pages folder and components folder.

asyncData() hook This hook has been around for a while now, and can be used only inside the Vue.js components stored in the pages folder.

You can read more about Data Fetching hooks here: Data Fetching.

Meta Tags and SEO

Nuxt.js makes it so intuitive to add SEO support to your SSR app. You can add Metadata to your app at two different levels:

  • Globally using the nuxt.config.js file
  • Locally inside a Nuxt.js Page

You can read about Meta Tags and SEO hooks here: Meta Tags and SEO.

Create our first Nuxt.js app

Let’s use the create-nuxt-app CLI, and create our first Nuxt.js app!

Before you start, you want to make sure you have all the perquisites required before you can install and run the CLI.

For this article, I am going to use npx. However, you can also use npm, or feel free to use yarn.

Step 0

Start by running the following command:

npx create-nuxt-app my-first-nuxt

This command uses the create-nuxt-app tool, and specifies the name of the project- in this case my-first-nuxt-app.

The CLI will ask you a few questions that are important to scaffold the new Nuxt.js app based on your own preferences and decisions. Here’s what to expect.

Step 1

First, let’s confirm the project name as shown in the Figure 1. Give the app a name and hit Enter.

Figure 1: Specify project name Figure 1: Specify project name

Step 2

You’ve got to choose whether you want to develop your app with TypeScript or JavaScript. I will select JavaScript as shown in Figure 2.

Figure 2: Programming language Figure 2: Programming language

Step 3

Next, you need to choose between Npm or Yarn. I will select Npm as shown in Figure 3.

Figure 3: Package manager Figure 3: Package manager

Step 4

In this step, you’ve got to select the UI framework you are going to use in the app. I will select Tailwind CSS as shown in Figure 4. Even if you skip this step, you can add any UI framework you want later.

Figure 4: UI framework Figure 4: UI framework

Step 5

Nuxt.js offers a set of modules that you can use right away in your apps. For this app, I will pick the Axios module. Figure 5 shows the selection.

Figure 5: Nuxt.js modules Figure 5: Nuxt.js modules

Step 6

The CLI makes it super intuitive to integrate linters in your app. I will pick up both ESLint and Prettier. Figure 6 shows the selection.

Figure 6: Linting tools Figure 6: Linting tools

Step 7

Now it’s time to select a testing framework. For the sake of this article, I will select None. Feel free to add any. Figure 7 shows the selection.

Figure 7: Testing framework Figure 7: Testing framework

Step 8

By default, Nuxt.js supports two rendering modes. SSR/SSG and SPA. I will pick SSR/SSG to take advantage of the Server-side rendering. Figure 8 shows the selection.

Figure 8: Rendering mode Figure 8: Rendering mode

Step 9

The deployment target depends on our selection in Step 8. In this case, we have two options to select from. Server (using a Node.js server hosting) or Static (CDN/JAMStack hosting). I will select the Server deployment target as shown in Figure 9.

Figure 9: Deployment target Figure 9: Deployment target_

Step 10

For the development tools, I will keep it simple and select the jsconfig.json option as shown in Figure 10.

Figure 10: Development tools Figure 10: Development tools

Step 11

I won’t be using any continuous integration for this app. I will simply select None as shown in Figure 11.

Figure 11: Continuous integration Figure 11: Continuous integration

Step 12

Finally, the CLI asks whether you want to use any version control system. A version control system is always recommended when doing any kind of development. I will select Git as shown in Figure 12.

Figure 12: Version control system Figure 12: Version control system

These twelve questions are enough for the CLI to start scaffolding and generating your app based on your preferences. It takes a few seconds to have everything ready for you.

If all goes well, you should see the following as in Figure 13.

Figure 13: create-nuxt-app new app instructions Figure 13: create-nuxt-app new app instructions

The CLI gives you instructions on how to run and build the app.

Step 13

Let’s run the app by following the steps highlighted in Figure 13. Run the following commands:

cd my-first-nuxt
npm run dev

The CLI compiles both the client and server parts of the app and starts the Node.js server on port 3000 as shown in Figure 14.

Figure 14: App is running Figure 14: App is running

Step 14

Open a browser instance and navigate to the URL http://localhost:3000/ and you should see the default Nuxt.js app rendering. Figure 15 shows the app running in a browser.

Figure 15: App rendering in a browser Figure 15: App rendering in a browser

That’s all you need to get started on your first Nuxt.js app. Enjoy!

Nuxt.js Directory Structure

Let’s quickly go through the different folders the CLI generated for us. I will start by opening the new app inside Visual Studio Code. Figure 16 shows the app open inside the editor.

Figure 16: App folders and files Figure 16: App folders and files

Let’s go through each folder, and explain their roles briefly.

.nuxt

The .nuxt folder is (re-)generated by the CLI every time you run or build the app. It has all the automatically generated files that Nuxt.js uses to run your app.

You can read more about the .nuxt folder here: .nuxt.

assets

The assets folder contains all of your uncompiled files such as Sass files, images, or font files. Nuxt.js makes use of Webpack to load all the files inside this folder.

You can read more about the assets folder here: assets.

components

This folder holds all of your Vue.js components. Nuxt.js components are not different from any other Vue.js component.

Read more about the components folder here: components.

layouts

This folder contains all of your layout components. These are Vue.js components with placeholders for content. At run time, the component and the layout it uses get merged together into a single component. Layouts in Nuxt.js allows you to define fixed UI sections in your app instead of having to repeat things over and over.

You can read more about the layouts folder here: layouts.

pages

This folder also holds Vue.js components. It is unique because Nuxt.js converts this folder structure (components with sub-folders) into actual Vue.js Routes.

You can read about the pages folder here: pages.

plugins

This folder contains global JavaScript functions that you want to run before Nuxt.js instantiates the root Vue.js app. These functions are called Plugins. They can take multiple forms. For instance, you create a Nuxt.js Plugin to load a Vue.js Plugin to your app. You can also install, and make use of a third-party Nuxt.js Plugin.

You can read more about the plugins folder here: plugins.

static

The name of this folder says it all! This folder is directly mapped to the server root. You can place any file in this folder that you do not want Webpack to process. For example, you can place a favicon file, any CSS files, and many other such files.

You can read more about the static folder here: static.

store

The store folder holds all the Vuex store files. Nuxt.js comes with the Vuex module installed, but keeps it disabled. In order to enable the Vue store in your Nuxt.js app, create an index.js file inside this folder, and Nuxt.js will automatically enable it for you.

You can read more about store folder here: store.

nuxt.config.js

As I mentioned, Nuxt.js prefers convention over configuration. However, at some times you may need to tweak the configuration a little. Nuxt.js provides the nuxt.config.js file to allow for custom configuration settings on the app level.

Read more about nuxt.config file here: nuxt.config.

That’s just a quick overview of what folders are generated by the Nuxt.js CLI. There are more you can read up on. You can find all the information you need on Nuxt.js Documentation website.

Conclusion

In this article, you were introduced to Nuxt.js and took a few baby steps towards creating your first Nuxt.js app. In the coming articles, we will immerse ourselves in the Nuxt.js world, and explore this fresh and promising web development framework together.

You can follow me on Twitter to see more of my work.

This Dot is a consultancy dedicated to guiding companies through their modernization and digital transformation journeys. Specializing in replatforming, modernizing, and launching new initiatives, we stand out by taking true ownership of your engineering projects.

We love helping teams with projects that have missed their deadlines or helping keep your strategic digital initiatives on course. Check out our case studies and our clients that trust us with their engineering.

You might also like

Awesome 3D experience with VueJS and TresJS: a beginner's guide cover image

Awesome 3D experience with VueJS and TresJS: a beginner's guide

Awesome 3D experience with VueJS and TresJS: a beginner's guide Vue.js developers are renowned for raving about the ease, flexibility, and speed of development their framework offers. Tres.js builds on this love for Vue by becoming the missing piece for seamless 3D integration. As a Vue layer for Three.js, Tres.js allows you to leverage the power of Three.js, a popular 3D library, within the familiar and beloved world of Vue components. This means you can create stunning 3D graphics and animations directly within your Vue applications, all while maintaining the clean and efficient workflow you've come to expect. TresJS is a library specifically designed to make incorporating WebGL (the web's 3D graphics API) into your Vue.js projects a breeze. It boasts several key features that make 3D development with Vue a joy: - Declarative Approach: Build your 3D scenes like you would any other Vue component, leveraging the power and familiarity of Vue's syntax. This makes it intuitive and easy to reason about your 3D elements. - Powered by Vite: Experience blazing-fast development cycles with Vite's Hot Module Replacement (HMR) that keeps your scenes updated in real-time, even as your code changes. - Up-to-date Features: Tres.js stays on top of the latest Three.js releases, ensuring you have immediate access to the newest features and functionality. - Thriving Ecosystem: The Tres.js ecosystem offers many resources to enhance your development experience. This includes: - Cientos: A collection of pre-built components and helpers that extend the capabilities of Tres.js, allowing you to focus on building your scene's functionality rather than reinventing the wheel (https://cientos.tresjs.org/). - TresLeches: A powerful state management solution specifically designed for 3D applications built with Tres.js (https://tresleches.tresjs.org/). You can try TresJS online using their official Playground or on their StackBlitz starter. But now, let's dive into a quick code example to showcase the simplicity of creating a 3D scene with TresJS. Setup First, install the package: npm install @tresjs/core three And then, if you are using Typescript, be sure to install the types: npm install @types/three -D If you are using Vite, now you need to modify your vite.config.ts file in this way to make the template compiler work with the custom renderer: ` Create our Scene Imagine a 3D scene as a virtual stage. To bring this stage to life, we need a few key players working together: 1. Scene: Think of this as the container that holds everything in your 3D world. It acts as the canvas where all the objects, lights, and the camera reside, defining the overall environment. 2. Renderer: This is the magician behind the curtain, responsible for taking all the elements in your scene and translating them into what you see on the screen. It performs the complex calculations needed to transform your 3D scene into 2D pixels displayed on your browser. 3. Camera: Like a real camera, this virtual camera defines the perspective from which you view your scene. You can position and adjust the camera to zoom in, zoom out, or explore different angles within your 3D world. - To make our camera dynamic and allow canvas exploration, we are going to leverage the client's OrbitControls component. Below are our examples. You will see that we just include the component in our canvas, and it just works. 4. Objects: These actors bring your scene to life. They can be anything from simple geometric shapes like spheres and cubes to complex models like characters or buildings. You create the visual elements that tell your story by manipulating and animating these objects. Starting from the beginning: to create our Scene with TresJS we just need to use our component TresCanvas in our Vue component's template: ` The TresCanvas component is going to do some setup work behind the scenes: - It creates a WebGLRenderer that automatically updates every frame. - It sets the render loop to be called on every frame based on the browser refresh rate. Using the window-size property, we force the canvas to take the width and height of our full window. So with TresCanvas component we have created our Renderer and our Scene. Let's move to the Camera: ` We just have to add the TresPerspectiveCamera component to our scene. NOTE: It's important that all scene-related components live between the TresCanvas component. Now, only the main actor is missing, let's add some styles and our object inside the scene. Our Vue component will now look like: ` And our scene will be: A Mesh is a basic scene object in three.js, and it's used to hold the geometry and the material needed to represent a shape in 3D space. As we can see, we can achieve the same with TresJS using the TresMesh component, and between the default slots, we are just passing our object (a Box in our example). One interesting thing to notice is that we don't need to import anything. That's because TresJS automatically generates a Vue Component based on the three objects you want to use in PascalCase with a Tres prefix. Now, if we want to add some color to our object the Three.js Material class comes to help us. We need to add: ` Conclusion Tres.js not only supercharges Vue.js applications with stunning 3D graphics, but it also integrates seamlessly with Nuxt.js, enabling you to harness the performance benefits of server-side rendering (SSR) for your 3D creations. This opens the door to building exceptional web experiences that are both interactive and performant. With Tres.js, Vue.js developers can leverage a declarative approach, cutting-edge features, and a vast ecosystem to bring their immersive web visions to life. If you want to elevate your Vue.js projects with a new dimension, Tres.js is an excellent choice to explore....

Understanding Vue.js's <Suspense> and Async Components cover image

Understanding Vue.js's <Suspense> and Async Components

In this blog post, we will delve into how and async components work, their benefits, and practical implementation strategies to make your Vue.js applications more efficient and user-friendly. Without further ado, let’s get started! Suspense Let's kick off by explaining what Suspense components are. They are a new component that helps manage how your application handles components that need to await for some async resource to resolve, like fetching data from a server, waiting for images to load, or any other task that might take some time to complete before they can be properly rendered. Imagine you're building a web page that needs to load data from a server, and you have 2 components that fetch the data you need as they will show different things. Typically, you might see a loading spinner or a skeleton while the data is being fetched. Suspense components make it easier to handle these scenarios. Instead of manually managing loading states and error messages for each component that needs to fetch data, Suspense components let you wrap all these components together. Inside this wrapper, you can define: 1. What to show while the data is loading (like a loading spinner). 2. The actual content that should be displayed once the data is successfully fetched. This way, Vue Suspense simplifies the process of handling asynchronous operations (like data fetching) and improves the user (and the developer) experience by providing a more seamless and integrated way to show loading states and handle errors. There are two types of async dependencies that can wait on: - Components with an async setup() hook. This includes components using with top-level await expressions. *Note: These can only be used within a component.* - Async Components. Async components Vue's asynchronous components are like a smart loading system for your web app. Imagine your app as a big puzzle. Normally, you'd put together all the pieces at once, which can take time. But what if some pieces aren't needed right away? Asynchronous components help with this. Here's how they work: - Load Only What's Needed: Just like only picking up puzzle pieces you need right now, asynchronous components let your app load only the parts that are immediately necessary. Other parts can be loaded later, as needed. - Faster Start: Your app starts up faster because it doesn't have to load everything at once. It's like quickly starting with the border of a puzzle and filling in the rest later. - Save Resources: It uses your web resources (like internet data) more wisely, only grabbing what’s essential when it's essential. In short, asynchronous components make your app quicker to start and more efficient, improving the overall experience for your users. Example: ` Combining Async Components and Suspense Let's explore how combining asynchronous components with Vue's Suspense feature can enhance your application. When asynchronous components are used with Vue's Suspense, they form a powerful combination. The key point is that async components are "suspensable" by default. This means they can be easily integrated with Suspense to improve how your app handles loading and rendering components. When used together, you can do the following things: - Centralized Loading and Error Handling: With Suspense, you don't have to handle loading and error states individually for each async component. Instead, you can define a single loading indicator or error message within the Suspense component. This unified approach simplifies your code and ensures consistency across different parts of your app. - Flexible and Clean Code Structure: By combining async components with Suspense, your code becomes more organized and easier to maintain. An asynchronous component has the flexibility to operate independently of Suspense's oversight. By setting suspensible: false in its options, the component takes charge of its own loading behavior. This means that instead of relying on Suspense to manage when it appears, the component itself dictates its loading state and presentation. This option is particularly useful for components that have specific loading logic or visuals they need to maintain, separate from the broader Suspense-driven loading strategy in the application. In practice, this combo allows you to create a user interface that feels responsive and cohesive. Users see a well-timed loading indicator while the necessary components are being fetched, and if something goes wrong, a single, well-crafted error message is displayed. It's like ensuring that the entire puzzle is either revealed in its completed form or not at all rather than showing disjointed parts at different times. How it works When a component inside the boundary is waiting for something asynchronous, shows fallback content. This fallback content can be anything you choose, such as a loading spinner or a message indicating that data is being loaded. Example Usage Let’s use a simple example: In the visual example provided, imagine we have two Vue components: one showcasing a selected Pokémon, Eevee, and a carousel showcasing a variety of other Pokémon. Both components are designed to fetch data asynchronously. Without , while the data is being fetched, we would typically see two separate loading indicators: one for the Eevee Pokemon that is selected and another for the carousel. This can make the page look disjointed and be a less-than-ideal user experience. We could display a single, cohesive loading indicator by wrapping both components inside a boundary. This unified loading state would persist until all the data for both components—the single Pokémon display and the carousel—has been fetched and is ready to be rendered. Here's how you might structure the code for such a scenario: ` Here, is the component that's performing asynchronous operations. While loading, the text 'Loading...' is displayed to the user. Great! But what about when things don't go as planned and an error occurs? Currently, Vue's doesn't directly handle errors within its boundary. However, there's a neat workaround. You can use the onErrorCaptured() hook in the parent component of to catch and manage errors. Here's how it works: ` If we run this code, and let’s say that we had an error selecting our Pokemon, this is how it is going to display to the user: The error message is specifically tied to the component where the issue occurred, ensuring that it's the only part of your application that shows an error notification. Meanwhile, the rest of your components will continue to operate and display as intended, maintaining the overall user experience without widespread disruption. This targeted error handling keeps the application's functionality intact while indicating where the problem lies. Conclusion stands out as a formidable feature in Vue.js, transforming the management of asynchronous operations into a more streamlined and user-centric process. It not only elevates the user experience by ensuring smoother interactions during data loading phases but also enhances code maintainability and application performance. I hope you found this blog post enlightening and that it adds value to your Vue.js projects. As always, happy coding and continue to explore the vast possibilities Vue.js offers to make your applications more efficient and engaging!...

Making sense of Multiple v-model Bindings in Vue 3 cover image

Making sense of Multiple v-model Bindings in Vue 3

This article is one of a series of articles on what’s new in Vue 3. If you haven’t checked that series yet, you can do so by visiting the links below: - Take your App to the Next Level with Vue 3 - Async Components in Vue 3 - Teleporting in Vue 3 - Your first Vue 3 app using TypeScript - Vue 3 Composition API, do you really need it? In this installment, I will introduce the new v-model in Vue 3 and go through a new feature that allows you to use multiple v-model on the same component! By design, the v-model directive allows us to bind an input value to the state of an app. We use it to create a two-way data binding on the form input, textarea, and select elements. It handles updates in two opposite directions: When the input value changes, it reflects the value onto the state inside the Component. When the Component state changes, it reflects the changes onto the form input elements. The core concept of v-model remains the same in Vue 3 with more enhancements and features. Let’s dig in! Vue 2: v-model Vue 2 supports a single v-model on any given Component. In Vue 2, to build a complex Component that supports two-way data binding, it utilizes a single v-model with one full-blown payload. The Component handles the state internally for all the input elements. It generates a single payload object representing the state of the Component. Finally, it emits an event to the parent Component with the payload attached. This method had several pitfalls, especially for creating Vue UI Libraries. Of these pitfalls is the vagueness of the payload interface. It’s unclear what’s being included in the payload. A developer had to loop through the payload object in order to uncover what properties were there. Another is the need to write the logic inside the Component to handle the internal state and the generation of the payload object. Shortly, we will uncover what has been improved in this regard with Vue 3. However, before this, let’s review some basics on how Vue 2 handles implementing two-way data binding in Components. Vue 2: Two-way Data Binding As mentioned, Vue 2 uses the v-model directive to support two-way data binding on Components. Internally, it follows certain steps and rules in order to support the v-model directive. By default, the v-model directive uses different properties and emits different events for different input elements: Text and Textarea elements use the value property and the input event Checkboxes and Radio buttons use the checked property and the change event Select fields use the input property and the change event. Building a Component with a single input element will internally use something similar to the snippet below: ` The custom Component above defines a single prop named value as follows: ` Then, in the parent Component, you use the new custom Component as follows: ` The v-model directive assumes that the CustomComponent defines an internal property named value and emits a single event named input. What if the CustomComponent has to handle multiple inputs? How do we accomplish that in Vue 2? Well, there is no official solution. However, there are two methods that you can use: The CustomComponent defines a single property named value of type Object. Internally, it parses the object into data fields and does the mapping manually on the template. On every change of any of the fields, it prepares a payload for all the fields and emits a single input event, and attaches the payload. That’s a lot of code to write for such a custom component. The other option is to skip using the v-model directive and instead utilize individual input/event pairs. I will illustrate this in a moment. Assuming you have a custom Component to handle the user’s first name and last name, you would employ something similar: ` As for the properties, the Component defines the following: ` Finally, the parent Component uses the new component as follows: ` We are not using the v-model anymore and providing multiple two-way data bindings on the new component. Further your understanding by reading the official docs on Using v-model on Components Vue 3: v-model In Vue 3, the v-model directive has had an overhaul to give developers more power and flexibility when building custom components that support two-way data binding. The v-model directive now supports new defaults. The default v-model property is renamed to modelValue instead of the old name of value. The default v-model event is renamed to update:modelValue instead of the old name of input. You might be thinking that's more typing when using the new v-model directive. The Vue team are one step ahead and have given you a shorthand to use instead. Let’s rebuild the custom component using it. ` The custom component defines a single prop named modelValue as follows: ` Then, in the parent component, use the new custom component as follows: ` The new v-model directive offers the new shorthand that is used like this: ` The v-model directive assumes that the CustomComponent defines an internal property named modelValue and emits a single event named update:ModelValue. In case you don’t want to use the default naming convention, feel free to use another name. Just remember to be consistent when naming properties. Here’s an example of using a custom name for the modelValue property. ` The custom component above defines a single prop named modelValue as follows: ` Then, in the parent component, you use the new custom component like so: ` Notice the use of the property fullName instead of the default property name. Vue 3: Multiple v-model directive bindings I hope the Vue 3 shorthand form of the v-model directive has given you a "hand up". With this, the v-model gives the flexibility to use multiple v-model directives on a single component instance. The modelValue can be renamed to whatever you want, allowing you to do this! This great new feature eliminates the previous two solutions I offered up on handling complex custom components for Vue 2. Let's jump in and go through an example demonstration! Demo - Multiple v-model directive bindings Let’s build a custom Address component that can be embedded in any form to collect a user’s address. > You can play with the example live on: vue3-multiple-v-model. > You can check the source code for the example on: vue3-multiple-v-model. Figure 1 below shows the final app in action. Let’s start by building the HTML template of the new component. Figure 1 shows that all the fields used are of type input elements. Except for the last one which is a checkbox element. Therefore, it’s suffice to focus on a single input field that will eventually be replicated for the rest of fields. ` The address-line input field binds the :value directive and the @input event as per the new v-model directive specifications in Vue 3. The component defines the following property: ` The other fields follow the same structure and naming convention. Let’s look at the checkbox field and see how it’s defined: ` In the case of a checkbox field element, we bind to the :checked directive instead of the :value directive. Also, we use the @change event instead of the @input event as in the case of input field elements. The event name follows the same standard way of emitting events in the new v-model directive. The component defines the following property: ` Let’s now embed the new custom Address component into the App component: ` For each and every property on the custom component, we bind using the v-model:{property-name} format. The modelValue was replaced with the specific property names we have in hand. When there was a single input binding, the shorthand format was so much easier. However, when there are multiple input elements, the modelValue is in a league of its own! Now, let’s define the properties inside the App component using the new Composition API setup() function: ` You create a new reactive property with an object payload. Finally, you return the reactive property to the component and use it to set bindings on the custom Address component as follows: ` That’s it! Conclusion Vue 3 has many new features and improvements. Today, we saw how we use multiple v-model directives on a single component instance. There is so much more to learn and uncover in Vue 3. The coming installments of this series will continue to look at different features to help you move from Vue 2 to Vue 3. Happy Vueing!...

Vercel & React Native - A New Era of Mobile Development? cover image

Vercel & React Native - A New Era of Mobile Development?

Vercel & React Native - A New Era of Mobile Development? Jared Palmer of Vercel recently announced an acquisition that spiked our interest. Having worked extensively with both Next.js and Vercel, as well as React Native, we were curious to see what the appointment of Fernando Rojo, the creator of Solito, as Vercel's Head of Mobile, would mean for the future of React Native and Vercel. While we can only speculate on what the future holds, we can look closer at Solito and its current integration with Vercel. Based on the information available, we can also make some educated guesses about what the future might hold for React Native and Vercel. What is Solito? Based on a recent tweet by Guillermo Rauch, one might assume that Solito allows you to build mobile apps with Next.js. While that might become a reality in the future, Jamon Holmgren, the CTO of Infinite Red, added some context to the conversation. According to Jamon, Solito is a cross-platform framework built on top of two existing technologies: - For the web, Solito leverages Next.js. - For mobile, Solito takes advantage of Expo. That means that, at the moment, you can't build mobile apps using Next.js & Solito only - you still need Expo and React Native. Even Jamon, however, admits that even the current integration of Solito with Vercel is exciting. Let's take a closer look at what Solito is according to its official website: > This library is two things: > > 1. A tiny wrapper around React Navigation and Next.js that lets you share navigation code across platforms. > > 2. A set of patterns and examples for building cross-platform apps with React Native + Next.js. We can see that Jamon was right - Solito allows you to share navigation code between Next.js and React Native and provides some patterns and components that you can use to build cross-platform apps, but it doesn't replace React Native or Expo. The Cross-Platformness of Solito So, we know Solito provides a way to share navigation and some patterns between Next.js and React Native. But what precisely does that entail? Cross-Platform Hooks and Components If you look at Solito's documentation, you'll see that it's not only navigation you can share between Next.js and React Native. There are a few components that wrap Next.js components and make them available in React Native: - Link - a component that wraps Next.js' Link component and allows you to navigate between screens in React Native. - TextLink - a component that also wraps Next.js' Link component but accepts text nodes as children. - MotiLink - a component that wraps Next.js' Link component and allows you to animate the link using moti, a popular animation library for React Native. - SolitoImage - a component that wraps Next.js' Image component and allows you to display images in React Native. On top of that, Solito provides a few hooks that you can use for shared routing and navigation: - useRouter() - a hook that lets you navigate between screens across platforms using URLs and Next.js Url objects. - useLink() - a hook that lets you create Link components across the two platforms. - createParam() - a function that returns the useParam() and useParams() hooks which allow you to access and update URL parameters across platforms. Shared Logic The Solito starter project is structured as a monorepo containing: - apps/next - the Next.js application. - apps/expo or apps/native - the React Native application. - packages/app - shared packages across the two applications: - features - providers - navigation The shared packages contain the shared logic and components you can use across the two platforms. For example, the features package contains the shared components organized by feature, the providers package contains the shared context providers, and the navigation package includes the shared navigation logic. One of the key principles of Solito is gradual adoption, meaning that if you use Solito and follow the recommended structure and patterns, you can start with a Next.js application only and eventually add a React Native application to the mix. Deployments Deploying the Next.js application built on Solito is as easy as deploying any other Next.js application. You can deploy it to Vercel like any other Next.js application, e.g., by linking your GitHub repository to Vercel and setting up automatic deployments. Deploying the React Native application built on top of Solito to Expo is a little bit more involved - you cannot directly use the Github Action recommended by Expo without some modification as Solito uses a monorepo structure. The adjustment, however, is luckily just a one-liner. You just need to add the working-directory parameter to the eas update --auto command in the Github Action. Here's what the modified part of the Expo Github Action would look like: ` What Does the Future Hold? While we can't predict the future, we can make some educated guesses about what the future might hold for Solito, React Native, Expo, and Vercel, given what we know about the current state of Solito and the recent acquisition of Fernando Rojo by Vercel. A Competitor to Expo? One question that comes to mind is whether Vercel will work towards creating a competitor to Expo. While it's too early to tell, it's not entirely out of the question. Vercel has been expanding its offering beyond Next.js and static sites, and it's not hard to imagine that it might want to provide a more integrated, frictionless solution for building mobile apps, further bridging the gap between web and mobile development. However, Expo is a mature and well-established platform, and building a mobile app toolchain from scratch is no trivial task. It would be easier for Vercel to build on top of Expo and partner with them to provide a more integrated solution for building mobile apps with Next.js. Furthermore, we need to consider Vercel's target audience. Most of Vercel's customers are focused on web development with Next.js, and switching to a mobile-first approach might not be in their best interest. That being said, Vercel has been expanding its offering to cater to a broader audience, and providing a more integrated solution for building mobile apps might be a step in that direction. A Cross-Platform Framework for Mobile Apps with Next.js? Imagine a future where you write your entire application in Next.js — using its routing, file structure, and dev tools — and still produce native mobile apps for iOS and Android. It's unlikely such functionality would be built from scratch. It would likely still rely on React Native + Expo to handle the actual native modules, build processes, and distribution. From the developer’s point of view, however, it would still feel like writing Next.js. While this idea sounds exciting, it's not likely to happen in the near future. Building a cross-platform framework that allows you to build mobile apps with Next.js only would require a lot of work and coordination between Vercel, Expo, and the React Native community. Furthermore, there are some conceptual differences between Next.js and React Native that would need to be addressed, such as Next.js being primarily SSR-oriented and native mobile apps running on the client. Vercel Building on Top of Solito? One of the more likely scenarios is that Vercel will build on top of Solito to provide a more integrated solution for building mobile apps with Next.js. This could involve providing more components, hooks, and patterns for building cross-platform apps, as well as improving the deployment process for React Native applications built on top of Solito. A potential partnership between Vercel and Expo, or at least some kind of closer integration, could also be in the cards in this scenario. While Expo already provides a robust infrastructure for building mobile apps, Vercel could provide complementary services or features that make it easier to build mobile apps on top of Solito. Conclusion Some news regarding Vercel and mobile development is very likely on the horizon. After all, Guillermo Rauch, the CEO of Vercel, has himself stated that Vercel will keep raising the quality bar of the mobile and web ecosystems. While it's unlikely we'll see a full-fledged mobile app framework built on top of Next.js or a direct competitor to Expo in the near future, it's not hard to imagine that Vercel will provide more tools and services for building mobile apps with Next.js. Solito is a step in that direction, and it's exciting to see what the future holds for mobile development with Vercel....

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.

Prefer email? hi@thisdot.co