The isMobile variable from useSettings is failing to update correctly when the window is resized in a Next

I’ve encountered an issue with determining the device type (mobile, tablet, or desktop) in my Next.js application. I’ve utilized the is-mobile npm package to identify the device type and passing this data through settings. However, the isMobile flag fails to update correctly when I resize the browser window using Chrome’s responsive mode. Even when switching to mobile view, it remains false.

The implementation spans across 3 different files:

In useSetting.ts: I’m deconstructing the settings as shown in the code snippet below:

import useStore from '~/hooks/useStore';

export const useSettings = () => {
  const [{ settings }] = useStore();

  return settings;
};

The settings are retrieved via useStore.ts. In useStore.ts:

import type { Action } from 'react-sweet-state';
import { createHook, createStore } from 'react-sweet-state';

interface iStates {
  settings: iSettings;
}
const actions = {
  setSettings: (settings: Record<any, any>): Action<iStates> => {
    return ({ setState }) => {
      setState({ settings });
    };
  },
};

const store = createStore<iStates, typeof actions>({
  initialState: {
    settings: {},
  },
  actions,
});

export default createHook(store);

During the settings initialization, a warning is generated: Type '{}' is missing the following properties from type 'iSettings': isMobile, isPhone, isTablet, isDesktop, and 3 more.

The interface of iSettings is:

interface iSettings {
  isMobile: boolean;
  isPhone: boolean;
  isTablet: boolean;
  isDesktop: boolean;
  menu: {
    primary: iPrimaryMenuItem[];
    footer: iPrimaryMenuItem[];
    socials: Array<{ url: string }>;
  };
  lastUpdate: string;
  contactEmails: iContactEmails['emails'];
}

When setting the state in actions, another warning arises:

Type 'Record<any, any>' is missing the following properties from type 'iSettings': isMobile, isPhone, isTablet, isDesktop, and 3 more.

Next, in _app.tsx: I update the settings in the useEffect hook and then pass the settings to the Header file.

import type { NextPageContext } from 'next';
import type { AppProps } from 'next/app';
import { useEffect } from 'react';
import { PagesProgressBar as ProgressBar } from 'next-nprogress-bar';
import { MantineProvider } from '@mantine/core';
import { APIProvider } from '@vis.gl/react-google-maps';
import { useIsBusiness } from '~/hooks';
import useStore from '~/hooks/useStore';
import { getPrimaryMenu, rawFetch } from '~/utilities';
import clsx from 'clsx';
import md from 'is-mobile';
import { Toaster } from 'react-hot-toast';
import '../assets/css/style.css';

App.getInitialProps = async (ctx: NextPageContext) => {
  const ua = ctx.req?.headers?.['user-agent'];
  const isMobile = md({ ua, tablet: true });
  const isPhone = md({ ua });
  const isTablet = isMobile && !isPhone;
  const isDesktop = !isMobile;

  const primaryMenu: iMenu = await rawFetch('/menus/v1/menus/primary');
  const socialsMenu: iMenu = await rawFetch('/menus/v1/menus/socials');
  const footerMenu: iMenu = await rawFetch('/menus/v1/menus/footer');
  const contactEmails: iContactEmails = await rawFetch('/acf/v3/options/options/emails');
  const pages = await rawFetch('/wp/v2/pages', { params: { per_page: 1 } });

  return {
    settings: {
      isMobile,
      isPhone,
      isTablet,
      isDesktop,
      menu: {
        primary: getPrimaryMenu(primaryMenu),
        footer: getPrimaryMenu(footerMenu),
        socials: socialsMenu.items?.map(({ url }) => ({ url })),
      },
      lastUpdate: pages?.[0]?.modified,
      contactEmails: contactEmails?.emails,
    },
  };
};
export default function App({ Component, pageProps, settings }: AppProps) {
  const [, { setSettings }] = useStore();
  const isBusiness = useIsBusiness();

  useEffect(() => {
    setSettings(settings);
  }, []);

  return (
    <APIProvider apiKey="AIzaSyDoOlmYovBjVqFi9lZKcuOt0xMSEb15OYc">
      <div className={clsx(isBusiness && 'dark')}>
        <div className="dark:bg-gray-900">
          <MantineProvider>
            <Component {...pageProps} />
          </MantineProvider>
          <ProgressBar height="4px" color="rgb(230 178 0)" options={{ showSpinner: false }} shallowRouting />
          <Toaster position="top-right" toastOptions={{ style: { borderRadius: '0', background: '#333', color: '#fff' } }} />
        </div>
      </div>
    </APIProvider>
  );
}

In _app.tsx, a warning also appears on the default App function:

Property 'settings' does not exist in type 'AppProps'.

I've researched solutions on Chatgpt suggesting to extend AppProps, but this hasn't resolved the issue. As a newcomer to TypeScript and Next JS, I'm seeking further guidance.

Answer №1

According to the is-mobile library, it does not rely on window size but rather on meta data such as browser type and user agent.

Therefore, changing the window size will not have any effect.

The npm package describes it as:

Check if mobile browser, based on useragent string.

Regarding your TypeScript concern, you can extend the AppProps type like this:

// Instead of any, you can define your own settings type.
type ExtendedAppProps = AppProps & { settings: any };

export default function App({ Component, pageProps, settings }: ExtendedAppProps)

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

Tips to tackle a nextauth client fetch error - What to do next?

I have deployed a Next.js application and decided to include NextAuth in it. Everything works as expected on localhost. However, when I switch to production mode, I receive a client_fetch_error: [next-auth][error][CLIENT_FETCH_ERROR] JSON.parse: unexpect ...

An issue was encountered in the karma/config.tpl.ts file at line 13, column 18 - a TS1109 error indicating that an expression was expected. This

I'm encountering the following error after updating to Angular 9, so I haven't downgraded TypeScript. Could someone please assist me? I've tried numerous solutions without success. node_modules/karma/config.tpl.ts:66:16 - error TS1005: &apo ...

Issue encountered when executing the migration fresh seed: SyntaxError, which indicates the absence of a closing parenthesis after the

Having trouble with a nextJS project that utilizes mikro-orm? Struggling to overcome this persistent error for days: C:\Users\BossTrails\Documents\core.nest-main_2\node_modules\.bin\mikro-orm:2 basedir=$(dirname "$(e ...

The swipe motion will be executed two times

By pressing the Circle button, the Box will shift to the right and vanish from view. Further details (FW/tool version, etc.) react scss Typescript framer-motion import "./style.scss"; import React, { FunctionComponent, useState } from &q ...

Encountering a 500 error code while attempting to send a post request using Angular

Whenever I attempt to send a post request to Django server, I encounter a 500 (Internal Server Error) response. Interestingly, the get and put requests work flawlessly on the same server where Django is connected to PostgreSQL database. Here is a snippet ...

implementing a one-time action when SWR-fetched data becomes accessible (using useEffect)

Imagine I need to run a code snippet once and only once when SWR successfully retrieves the data. const { data, isLoading, mutate, } = useSWR(`${process.env.BACKEND_BASE_URL}/resource`,fetcher); Typically, you would achieve this using a useE ...

Exploring the use of getServerSideProps within a React context (specifically within the Next.js pages

I am facing a dilemma while working with Next.js and the pages router. The issue revolves around managing the global context of my application using react createContext. My requirement is to fetch data using getServerSideProps and store the result in a gl ...

Unable to locate the specified environment variable in the current nest

Currently, I am referring to the official documentation on the NestJs website that provides a guide on using config files: https://docs.nestjs.com/techniques/configuration Below is the code snippet I am working with: app.module import { Module } from &ap ...

We are currently experiencing issues with our Facebook ad not loading on iOS 14.7.1

After advertising on Facebook for our website, we noticed that iPhone users with the current IOS (14.7.1) version are encountering an error ("An unexpected error has occurred") in the Facebook browser when clicking on the ad. Interestingly, other companies ...

Is it possible to conditionally trigger useLazyQuery in RTK Query?

Is it possible to obtain trigger from useLazyQuery conditionally? const [trigger] = props.useLazySearchQuery(); My objective is to retrieve trigger only when useLazySearchQuery is provided in the props. One way I can achieve this is by using const [ ...

Using useRef as a prop in React with TypeScript

I am currently experimenting with TypeScript and encountering an issue when trying to use useRef in a custom element specifically when passing it as a prop I have attempted the following: import React from "react"; export interface InputProps extends ...

Is there a way to find the recursive key types in TypeScript?

Is there a method to ensure that code like this can compile while maintaining type safety? type ComplexObject = { primitive1: boolean; complex: { primitive2: string; primitive3: boolean; } }; interface MyReference { myKey: keyof ComplexObj ...

Tips for preventing the need to convert dates to strings when receiving an object from a web API

I am facing an issue with a class: export class TestClass { paymentDate: Date; } Whenever I retrieve an object of this class from a server API, the paymentDate field comes as a string instead of a Date object. This prevents me from calling the ...

The initial rendering of the NextJs 13 application is experiencing significant sluggishness when deployed on an EC2

After deploying my NextJS 13.4 app on an AWS EC2 instance with 2 GB of RAM, I noticed that the initial load time is quite slow, taking around 20 seconds to load for the first time. The development mode in NextJS builds and displays the result, which may co ...

Tips for integrating the react-financial-charts library into your React and JavaScript project

While exploring the react-financial-charts library, I discovered that it is written in TypeScript (TS). Despite my lack of expertise in TypeScript, I am interested in using this library in my React+JS project due to its active contributions. However, I hav ...

Group data by two fields with distinct values in MongoDB

I have developed a Typescript Node.js application and I am looking to organize documents by two fields, "one_id" and "two_id", based on a specific "one_id" value. Below is the data within my collection: { "_id":"5a8b2953007a1922f00124fd", "one_id ...

Troubleshooting tsconfig configuration issue in Visual Studio Code for ExpressJS with TypeScript and Vitest integration testing

Let's dive right in with an illustration: Here is a simplified version of my project structure: src/ app.ts test/ integration/ example.spec.ts tsconfig.json tsconfig.json The main tsconfig.json file includes these settings: { & ...

Elevate your Material UI Avatar with an added level of

Attempting to give a MUI Avatar component some elevation or shadow according to the documentation provided here. <Avatar alt="Cindy Baker" src="/static/images/avatar/3.jpg" /> Enclosing the Avatar within a paper or Card element increases the size o ...

Utilize JavaScript libraries in a TypeScript project

Looking to integrate a payment system called iyzico into my project. The iyzico payment library can be found here. However, there are no types available for it. How can I utilize this library in my Node.js TypeScript Express backend project? I attempted t ...

When trying to use `slug.current` in the link href(`/product/${slug.current}`), it seems to be undefined. However, when I try to log it to the console, it is displaying correctly

import React from 'react'; import Link from 'next/link'; import { urlFor } from '../lib/clients'; const Product = ({ product: { image, name, slug, price } }) => { return ( <div> <Link href={`/product/ ...