Missing App Bridge type declarations for s-app-nav

Background

While converting our app from using @shopify/app-bridge-react to the CDN implementation, I’m converting the navigation to use the s-app-nav element:

import { useTranslation } from 'react-i18next';

export default function AppNavigation() {
  const { t } = useTranslation();

  return (
    <s-app-nav>
      <s-link href="/app" rel="home">
        {t('navigation.home')}
      </s-link>
      <s-link href="/app/media">{t('navigation.media')}</s-link>
      <s-link href="/app/feeds">{t('navigation.feeds')}</s-link>
      <s-link href="/app/analytics">{t('navigation.analytics')}</s-link>
      <s-link href="/app/settings">{t('navigation.settings')}</s-link>
    </s-app-nav>
  );
}

I’ve defined the types by installing both @shopify/app-bridge-types@0.5.3 and @shopify/polaris-types@1.0.1 and configuring them in env.d.ts:

/// <reference types="@shopify/polaris-types" />
/// <reference types="@shopify/app-bridge-types" />

Errors

Currently, TypeScript is throwing an error on s-app-nav:

Property ‘s-app-nav’ does not exist on type ‘JSX.IntrinsicElements’.ts(2339)

s-link is throwing the error:

Type ‘{ children: string; href: string; rel: string; }’ is not assignable to type ‘ReactProps$w & ReactBaseElementPropsWithChildren’.
Property ‘rel’ does not exist on type ‘ReactProps$w & ReactBaseElementPropsWithChildren’.ts(2322)

Temporary solution

I’ve manually defined both elements that are throwing an error in env.d.ts:

import 'react';

// Missing Shopify App Bridge web components types
declare module 'react' {
  namespace JSX {
    interface IntrinsicElements {
      's-app-nav': React.DetailedHTMLProps<
        React.HTMLAttributes<HTMLElement>,
        HTMLElement
      >;
      's-link': React.DetailedHTMLProps<
        React.AnchorHTMLAttributes<HTMLAnchorElement>,
        HTMLAnchorElement
      >;
    }
  }
}

Question

Am I missing a configuration option or are these types misconfigured in the App Bridge types package?

I have the same problem with `ui-save-bar`, then try to investigate why this error happen.

I think that there is a minor difference in declaration of components in @shopify/polaris-types (Typescript OK) and @shopify/app-bridge-types(Typescript error).

In @shopify/polaris-types, one element is declared both in module react and global.

// @shopify/polaris-types
declare module 'react' {
    namespace JSX {
        interface IntrinsicElements {
            [tagName$4]: Omit<ReactProps$4, 'accessory'> & ReactBaseElementProps<TextField>;
        }
    }
}
declare global {
    namespace JSX {
        interface IntrinsicElements {
            [tagName$4]: Omit<ReactProps$4, 'accessory'> & ReactBaseElementProps<TextField>;
        }
    }
}

but in @shopify/app-bridge-types declare only global:

// @shopify/app-bridge-types
declare global {
  namespace JSX {
    interface IntrinsicElements extends AppBridgeElements {}
  ...

So I tried this solution, it’s worked for me.

// custom-elements.d.ts

import * as React from 'react';
import {
  UIModalAttributes,
  SAppWindowAttributes,
  UINavMenuAttributes,
  SAppNavAttributes,
  UISaveBarAttributes,
  UITitleBarAttributes,
  SPageAttributes,
} from '@shopify/app-bridge-types';

interface AppBridgeElements {
  'ui-modal': UIModalAttributes;
  's-app-window': SAppWindowAttributes;
  'ui-nav-menu': UINavMenuAttributes;
  's-app-nav': SAppNavAttributes;
  'ui-save-bar': UISaveBarAttributes;
  'ui-title-bar': UITitleBarAttributes;
  's-page': SPageAttributes;
}

declare module 'react' {
  namespace JSX {
    interface IntrinsicElements extends AppBridgeElements {}
  }
}



// tsconfig.json
...
"include": [
   custom-elements.d.ts
   ...

Hope this help.