I followed the tutorial to upgrade a Remix template app to React Router, and now the app is running well. I want to try the Polars web component, but I found that VSCode doesn't recognize them.
it seems there is no s-app-nav(using ui-nav-menu is ok).
Other web components are ok.

Here is my package.json:
"dependencies": {
"@react-router/dev": "^7.9.1",
"@react-router/fs-routes": "^7.9.1",
"@react-router/node": "^7.9.1",
"@react-router/serve": "^7.9.1",
"@shopify/app-bridge-react": "^4.1.6",
"@shopify/polaris": "^12.0.0",
"@shopify/shopify-app-react-router": "^1.0.0",
"@shopify/shopify-app-session-storage-drizzle": "^2.0.17",
"dotenv": "^16.5.0",
"drizzle-orm": "^0.41.0",
"isbot": "^5.1.0",
"mysql2": "^3.14.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-router": "^7.9.1",
"uuid": "^11.1.0",
"vite-tsconfig-paths": "^5.0.1"
},
"devDependencies": {
"@shopify/api-codegen-preset": "^1.1.1",
"@shopify/polaris-types": "^1.0.0",
"@types/eslint": "^9.6.1",
"@types/node": "^22.2.0",
"@types/react": "^18.2.31",
"@types/react-dom": "^18.2.14",
"@typescript-eslint/eslint-plugin": "^6.7.4",
"@typescript-eslint/parser": "^6.7.4",
"eslint": "^8.38.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-jsx-a11y": "^6.7.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"prettier": "^3.2.4",
"typescript": "^5.2.2",
"vite": "^6.2.2",
"drizzle-kit": "^0.30.6",
"tsx": "^4.19.3"
},
(same as the new template with drizzle-kit and tsx)
my tsconfig.json:
{
"include": [
"env.d.ts",
"**/*.ts",
"**/*.tsx",
".react-router/types/**/*"
],
"compilerOptions": {
"lib": [
"DOM",
"DOM.Iterable",
"ES2022"
],
"strict": true,
"skipLibCheck": true,
"isolatedModules": true,
"allowSyntheticDefaultImports": true,
"removeComments": false,
"forceConsistentCasingInFileNames": true,
"noEmit": true,
"allowJs": true,
"resolveJsonModule": true,
"jsx": "react-jsx",
"module": "ESNext",
"moduleResolution": "Bundler",
"target": "ES2022",
"baseUrl": ".",
"types": [
"@react-router/node",
"vite/client",
"@shopify/polaris-types"
],
"rootDirs": [
".",
"./.react-router/types"
]
}
}
eslint is copied from the repo.
code:
import type { HeadersFunction, LoaderFunctionArgs } from "react-router";
import { Link, Outlet, useLoaderData, useRouteError } from "react-router";
import { boundary } from "@shopify/shopify-app-react-router/server";
import { AppProvider } from "@shopify/shopify-app-react-router/react";
import { AppProvider as PolarisAppProvider } from "@shopify/polaris";
import type {
LinkLikeComponent,
LinkLikeComponentProps,
} from "@shopify/polaris/build/ts/src/utilities/link";
import englishI18n from "@shopify/polaris/locales/en.json" with { type: "json" };
import React from "react";
import polarisStyles from "@shopify/polaris/build/esm/styles.css?url";
import { authenticate } from "../shopify.server";
import { refreshShopInfo } from "app/services/shop-service.server";
export const links = () => [{ rel: "stylesheet", href: polarisStyles }];
// PolarisLink adapter using imported types
const PolarisLink = React.forwardRef<HTMLAnchorElement, LinkLikeComponentProps>(
({ url, children, external, ...rest }, ref) => {
if (external) {
return (
<a href={url} ref={ref} {...rest}>
{children}
</a>
);
}
return (
<Link to={url} ref={ref} {...rest}>
{children}
</Link>
);
},
) as LinkLikeComponent;
PolarisLink.displayName = "PolarisLink";
export const loader = async ({ request }: LoaderFunctionArgs) => {
const { admin, session } = await authenticate.admin(request);
console.log("user visit", session.shop, request.url);
try {
await refreshShopInfo(admin);
} catch (error) {
console.error("refresh shop failed", error);
}
return { apiKey: process.env.SHOPIFY_API_KEY || "" };
};
export default function App() {
const { apiKey } = useLoaderData<typeof loader>();
return (
<AppProvider embedded apiKey={apiKey}>
<PolarisAppProvider i18n={englishI18n} linkComponent={PolarisLink}>
<s-app-nav>
<Link to="/app" rel="home">
Home
</Link>
<Link to="/app/config">Settings</Link>
<Link to="/app/subscribe">Membership</Link>
</s-app-nav>
<Outlet />
</PolarisAppProvider>
</AppProvider>
);
}
// Shopify needs Remix to catch some thrown responses, so that their headers are included in the response.
export function ErrorBoundary() {
return boundary.error(useRouteError());
}
export const headers: HeadersFunction = (headersArgs) => {
return boundary.headers(headersArgs);
};
I followed the tutorial to upgrade a Remix template app to React Router, and now the app is running well. I want to try the Polars web component, but I found that VSCode doesn't recognize them.
it seems there is no

s-app-nav(usingui-nav-menuis ok).Other web components are ok.
Here is my package.json:
(same as the new template with drizzle-kit and tsx)
my tsconfig.json:
{ "include": [ "env.d.ts", "**/*.ts", "**/*.tsx", ".react-router/types/**/*" ], "compilerOptions": { "lib": [ "DOM", "DOM.Iterable", "ES2022" ], "strict": true, "skipLibCheck": true, "isolatedModules": true, "allowSyntheticDefaultImports": true, "removeComments": false, "forceConsistentCasingInFileNames": true, "noEmit": true, "allowJs": true, "resolveJsonModule": true, "jsx": "react-jsx", "module": "ESNext", "moduleResolution": "Bundler", "target": "ES2022", "baseUrl": ".", "types": [ "@react-router/node", "vite/client", "@shopify/polaris-types" ], "rootDirs": [ ".", "./.react-router/types" ] } }eslint is copied from the repo.
code: