A new commer to solid.js
, I'm following a tutorial to get some A
routing in solid.js app's navbar . My App.jsx is code is like this:
import { Router, Route, A } from "@solidjs/router";
import Home from './pages/Home';
import About from './pages/About';
import Test from './routes/Test';
import Cart from './pages/Cart';
function App() {
const [darkTheme, setDarkTheme] = createSignal(false)
function toggleTheme() {
setDarkTheme(!darkTheme())
}
return (
<div class="container m-auto bg">
<header
class="my-4 p-2 text-xl flex items-center gap-4 justify-end"
classList={{"bg-neutral-900": darkTheme(), "text-white": darkTheme() }}
>
<span
class="material-symbols-outlined cursor-pointer"
onClick={toggleTheme}
>light_mode</span>
<h1 class="mr-auto">Ninja Merch</h1>
<A href="/">Home</A>
<A href="/cart">Cart</A>
</header>
<img class="rounded-md" src={banner} alt="site banner" />
<Router>
<Route path="/" component={Home} />
<Route path="/cart" component={Cart} />
</Router>
</div>
);
}
export default App;
However I get a blank screen with this console error:
utils.js?v=92765ccd:29 Uncaught
Error: <A> and 'use' router primitives can be only used inside a Route.
at invariant (utils.js?v=92765ccd:29:15)
at useRouter (routing.js?v=92765ccd:9:32)
at useRoute (routing.js?v=92765ccd:11:75)
at useResolvedPath (routing.js?v=92765ccd:13:19)
at A (components.jsx:15:14)
at chunk-JG2I5HKG.js?v=92765ccd:633:14
at untrack (chunk-JG2I5HKG.js?v=92765ccd:513:12)
at Object.fn (chunk-JG2I5HKG.js?v=92765ccd:629:11)
at runComputation (chunk-JG2I5HKG.js?v=92765ccd:809:22)
at updateComputation (chunk-JG2I5HKG.js?v=92765ccd:788:3)
I tried several different arrangements of A
tag to no avail.
The docs did not help either, as it does not have a similar example.
So appreciate your hints to fix this.
You can use an A element under a Route component as navigation items are always associated with a route.
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>
);
So, your app should look like this:
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);
If you want to pass A
directly as you did in your demo, you can create a wrapper component so that A
is always under a Router
component:
const Layout: Component<{ children: JSX.Element }> = (props) => {
return (
<div>
{props.children}
</div>
);
};
const Home: Component<{}> = () => (
<Layout>
<ul>
<li><A href='/'>Home</A></li>
<li><A href='/blog'>Blog</A></li>
<li><A href='/users'>Users</A></li>
</ul>
</Layout>
);
Alternatively, you can move the layout items including header under the 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>
);
};
Now, the App component becomes:
import { A, Route, Router } from '@solidjs/router';
import { Component, JSX } from 'solid-js';
import { render } from 'solid-js/web';
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>
const Users: Component<{}> = () => <Layout><div>This is Users page!</div></Layout>
const Blog: Component<{}> = () => <Layout><div>This is Blog page!</div></Layout>
const NotFound: Component<{}> = () => <Layout><div>Not Found!</div></Layout>
function App() {
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);
See this answer for details: SolidJS Uncaught Error: <A> and 'use' router primitives can be only used inside a Route