What are some ways to capture and save the window width prior to launching my Nuxt application?

I am working on a Nuxt application where I need to display different components based on the window width and send a request to create a session with the device width as one of the header parameters. Here is my approach:

In my store code:

//index.js
export const state = () => ({
  device_width: null,
  session_data : {},
 
})

export const mutations = {
  set_device_width(state, payload) {
    return state.device_width = payload;
  },
  set_session_data(state, payload){
     return state.session_data = payload
  }
}
export const actions = {

  //server init action to initialize the app with some necessary data
  async nuxtServerInit({ commit }) {

    
    if (process.browser) {
      commit('set_device_width', window.innerWidth);
    }
      var device_type = "";
      if (this.state.device_width < 768) {
        device_type = "mobile";
      } else if (this.state.device_width > 768) {
        device_type = "desktop";
      }
      var sessionData= await axios(...//api request with 'device_type' in header//....)
      commit('set_session_data', sessionData)

}

Then, in my templates, I use a computed method to retrieve the value.

computed:{
  isMobile(){
    return this.$store.state.device_width<768
  }
}

When the screen size is below 768, everything works fine. However, when in desktop mode with full-screen, there's a brief moment where isMobile is true before becoming false and the desktop component loads. This results in the session data always being created with "device_type: mobile" initially. Additionally, due to the initial mobile UI display, the SEO elements of the desktop UI do not function properly. How can I address this issue? I aim to determine the screen size and store it prior to app initialization. I believed using the serverInit action would achieve this.

Answer №1

It is impossible to obtain any device information on the server-side. The nuxtServerInit function runs on the server-side and does not have access to user device details, therefore using the window object in it is not possible.

An alternative approach would be to retrieve the device's width during the mounted or created lifecycle of your layouts and then store this information by committing it to the store. However, it is important to note that these actions will occur after your app has been initialized.

Answer №2

According to Tony, the ideal solution would involve more CSS work.

If you still wish to incorporate the device aspect, consider utilizing the fevid solution and implementing the following code for a more visual representation:

/layouts/LayoutDefault.vue

<script>
import { throttle } from 'lodash-es'

const watchResize = throttle(function () {
  console.log('resized properly')
  // Ensure to update your `device_type` using Vuex mutation/action
  // Perform axios call by accessing a const/let variable or global vuex state
}, 1000)

export default {
  mounted() {
    window.addEventListener('resize', watchResize)
  },
}
</script>

I strongly recommend using throttle, install it via yarn add -D lodash-es as monitoring resize events can be resource-intensive and affect UI performance.


PS: Avoid applying this in middleware, as eventListener will be attached on every route navigation.
For multiple layouts, it is advisable to detach the watcher in the beforeDestroy() hook.

To delve deeper into Nuxt's lifecycle, refer to: https://nuxtjs.org/docs/2.x/concepts/nuxt-lifecycle/#server
Note that nuxtServerInit operates exclusively on the server-side.


EDIT: Consider utilizing this module tailored for your requirements: https://github.com/nuxt-community/device-module

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Create a collection of functions within an array that each return promises

I have created 4 different functions that return promises. By running the "hello" function and passing each subsequent function into the next .then, you can generate a single long string output. var hello = function(str){ return Promise.resolve(str + "h ...

The Stepper StepIconComponent prop in MUI is experiencing issues when trying to render styles from the styles object, leading to crashes in the app

Struggling to find a way to apply the styles for the stepper component without using inline styles. I attempted to replicate Material UI's demo, but encountered an error. The code from Material UI's demo that I want to mimic is shown below: http ...

bind a class property dynamically in real-time

I need to dynamically generate a TypeScript class and then add a property to it on the go. The property could be of any type like a function, Promise, etc., and should use this with the intention that it refers to the class itself. let MyClass = class{ ...

How to Incorporate Routes as Subroutes in Express.js

I am currently working on constructing a modular express.js server with a well-organized structure. I have experimented with using routes similar to components in React. index.js var syncsingle = require('./XYZ/syncsingle'); app.get('/sync ...

Error in saving webpage as HTML

I have integrated FileSaver.js into my project to enable users to save web pages as HTML. The code below is triggered when a user clicks on the download button: var originalstr=$.ajax( { type: "GET", url:"url", async: false }).resp ...

What is the appropriate way to utilize `render_template` from Flask within Angular?

I'm facing an issue where I need to implement different routes for various Angular Material tabs. I have attempted to directly call Flask from the template, as demonstrated below, but unfortunately, I am unable to invoke render_template from Angular. ...

How does ng-repeat determine the presence of duplicates within an array of objects?

angular.module("myApp",[]) .controller("myCtrl",function($scope) { $scope.persons = [{name:"teja",age:11}, {name:"Ash",age:12}, {name:"teja",age:11}]; }); In ...

In Javascript, navigate to a specific section by scrolling down

Currently, I am in the process of enhancing my portfolio website. My goal is to incorporate a CSS class once the user scrolls to a specific section on the page. (I plan to achieve this using a JavaScript event). One approach I am considering is initially ...

Exploring the intersection of points within an aframe

When working with a point in 3D space, it can be difficult to interact with it using a cursor or mouse. However, in three.js, there is an example (https://threejs.org/examples/webgl_interactive_points.html) where the mouse can easily interact with points ...

Hover over the div to center an SVG inside it

Simply put, I am working on a design where a gradient bar moves above a specific element when hovered, creating a visual effect of a triangle. I am now looking for a way to center an SVG inside the element on hover, to create a similar triangular gradient ...

Unfortunately, CSS3 PIE is not compatible with border-radius and box-shadow properties

I created a basic HTML/CSS code for testing purposes, but I'm having trouble getting the library to function properly. I've placed the .htc, .php and .js files in the same directory as index.html, but it just won't work. Check out the code ...

Having trouble creating a PDF from HTML

Having trouble with generating PDFs using various libraries as I keep encountering the following error: Fatal Error: spawn UNKNOWN The code snippet looks like this: mammoth.convertToHtml({ path: './backend/common/template.docx' } ...

Updating textbox values with ajax results in the page refreshing and the newly assigned values being lost

I'm currently working on updating a section of my webpage using AJAX instead of C#, as I don't want the page to refresh. All I need to do is execute a SELECT query to retrieve the current client from the SQL database and populate the correspondin ...

Using jQuery, effortlessly scroll a div to a specific vertical position of your choice

After referring to this previous question: Scrollpane on the bottom, css is hacky, javascript is hard I followed the same scrolling method as explained in the accepted answer. Now there's a new requirement to select a specific item (e.g., through a ...

Axios could potentially neglect default headers in certain cases

In my nuxt project, I am utilizing axios for making requests. However, I have encountered an issue where the default headers are being ignored specifically on node.js. When I run the following code snippet on node.js: import axios from "axios"; ...

AngularJS NG-Grid displaying incorrect value for select cell

I'm working on creating a table with a column that needs to be selected based on a value received from the server. The server sends me 4 as the value, but the first option is always selected instead. $scope.lotteryOptions = { data: 'myDa ...

The Angular template driven forms are flagging as invalid despite the regExp being a match

My input looks like this: <div class="form-group"> <label for="power">Hero Power</label> <input [(ngModel)]="model.powerNumber" name="powerNumber" type="text" class="form-control" pattern="^[0-9]+$"id= ...

Ways to retrieve the responseText within the jqxhr.complete callback function

Apologies in advance for my lack of knowledge in JavaScript and jQuery, this question may seem basic. I've searched through the jQuery documentation and Google but couldn't find an answer. I am attempting to trigger an action on the response onc ...

The CORS middleware seems to be ineffective when used in the context of Node.js

I have set up my REST API on a Raspberry Pi server and connected it to the public using localtunnel. I am trying to access this API from a localhost Node.js application. The Node application is running on Express and includes some static JS files. However, ...

Exploring the Possibilities of Nipplejs Integration in Vue with Quasar

Trying to implement Nipplejs in my Vue Project using quasar Components. Installed nipplejs through npm install nipplejs --save. Attempted integration of the nipple with the code snippet below: <template> <div id="joystick_zone">&l ...