solid-js

SolidJS Uncaught Error: <A> and 'use' router primitives can be only used inside a Route


I got some issues with my solidjs (Vanilla JS) code. I try to build a small three page Website, just to print out some Information. I use vitejs, solidjs and tailwindcss. I was able to build the relevant sections, some reactivity and my desired three sites. All on its own works well. The thing I can't manage is Routing.

My index.html looks for the App.jsx. Within the App.jsx I do the relevant imports, load and display my components and render everything. It looks something like this:

import { render } from "solid-js/web";
import { Router, Route } from "@solidjs/router";
import "./app.css";
const root = document.getElementById("root");
import Header from "./components/Header";
import Footer from "./components/Footer";
import Home from "./pages/Home";
import Impressum from "./pages/Impressum";
import NotFound from "./pages/404";

function App() {
  return (
    <>
      <Header />
      <Router>
        <Route path="/" component={Home} />
        <Route path="/impressum" component={Impressum} />
        <Route path="*404" component={NotFound} />
      </Router>
      <Footer />
    </>
  );
}

render(() => <App />, root);

In the Header component is a navigation bar with links. I also import A from solidjs/router in it. It looks something like this (I don't show the styles and other functionality which works fine):

import { createSignal, onCleanup, onMount, createEffect } from "solid-js";
import { A } from "@solidjs/router";
//import LinkList from "./LinkList";
import { Collapse, Dropdown, Ripple, initTWE } from "tw-elements";
import logo from "../assets/logo.svg";

[...]

<nav>
 <ul>
  <li><A href ="/">Home</A></li>
  <li><A href ="/impressum">Impressum</A></li>
 </ul>
</nav>

Running the dev server gives me the following error:

Uncaught Error: and 'use' router primitives can be only used inside a Route.

I tried different wrappers, asked chatGPT and have been on Google for hours. I can't figure out what is wrong. I'm not very long into programming. Also English isn't my native language...


Solution

  • As the warning states, you can use an A element or other elements that rely on the router API under a Route component.

    The problem is that you have an A component directly under the Router component through the Header component but it should be wrapped by a Route first. So, you need to move those links under a component that is used for a path.

    The idea is that the navigation items are always associated with a route. It is like links can exist inside a page.

    import { A, Route, Router } from '@solidjs/router';
    import { render } from 'solid-js/web';
    
    function App() {  
      const Home = () => (
        <div>
          <ul>
            <li><A href='/blog'>Blog</A></li>
            <li><A href='/users'>Users</A></li>
          </ul>
          <div>This is home page!</div>
        </div>
      );
    
      const Users = () => <div>Users</div>;
      const Blog = () => <div>Blog</div>;
      const NotFound = () => <div>NotFound</div>;
    
      return (
        <Router>
          <Route path="/" component={Home} />
          <Route path="/users" component={Users} />
          <Route path="/blog" component={Blog} />
          <Route path="*404" component={NotFound} />
        </Router>
      );
    }
    
    render(() => <App />, document.body);
    

    Alternatively, you can use a layout component:

    const Layout: Component<{ children: JSX.Element }> = (props) => {
      return (
        <div>
          <ul>
            <li><A href='/'>Home</A></li>
            <li><A href='/blog'>Blog</A></li>
            <li><A href='/users'>Users</A></li>
          </ul>
          {props.children}
        </div>
      );
    };
    
    const Home: Component<{}> = () => <Layout><div>This is Home page!</div></Layout>
    

    The router above is intended to be used with server rendered app. If you are going to use it for SPA, make sure you use the hash mode router:

    import { HashRouter } from "@solidjs/router";
    

    Otherwise you will have page not found error when you refresh the page when you are on a sub-route.

    PS: Solid Router has undergone some major updates, I believe for better SSR support, this is one of the changes that is brought about the latest update.