Search code examples
javascriptsvelteroutify

How to Create Route Links with Svelte Routify


I am learning how to use Routify to wire up some routes and links. I need help.

At the Routify docs it says:

"Links can be handled in an array of different ways. This might be the easiest way".

via: https://routify.dev/guide/navigation

It then gives this example:

<script>
  import {isActive, url} from '@sveltech/routify'

  const links =
  [
    ['./index', 'Home'], //add index if you don't want siblings to be considered children
    ['./blog', 'Blog'],
    ['./about', 'About'],
    ['./contact', 'Contact']
  ]
</script>

<style>
  .active {font-weight: bold}
</style>

<ul>
  {#each links as [path, name]}
    <!-- Svelte magic. If isActive is true, the "active" class is applied. -->
    <li class:active={$isActive(path)}>
      <a href={$url(path)}>
        {name}
      </a>
    </li>
  {/each}
</ul>

Unfortunately it doesn't give any instructions on how to wire this up to your app (if it does it's too complex for me to figure out).

I am using the Routify Template and I have copied the above code into the following directory:

pages/_components/Navigation.svelte

I then attempted to import it into pages/index.svelte as so:

pages/index.svelte

 <script>

  import Navigation from './_components/Navigation.svelte';

</script>

<div>
  <Navigation/>


</div>

The links appear at the top of the page. When I click them the endpoint follows this pattern:

http://localhost:5000/index/home

http://localhost:5000/index/blog

http://localhost:5000/index/about

http://localhost:5000/index/contact

In my /pages directory I have pages that match the pages listed in the code such as:

/pages/Home.svelte

When I click the links my browser stays on the same page and does not embed the page associated with the link. Also, my browser developer tools say:

Uncaught Error: Route could not be found for "/index/home".
    at urlToRoute (urlToRoute.js:15)
    at updatePage (navigator.js:13)
    at pushstate (navigator.js:60)
    at History.history.<computed> [as pushState] (navigator.js:51)

What do I need to do so that I can see the respective pages and why is their an intermediate directory named "index"? How do I get rid of the word "index" in the url ?


UPDATE

Okay I have the navigation listed on all pages and semi-working.

I have my Navigation code (below) imported into pages/_layout.svelte.

The code is as follows:

pages/_layout.svelte

<script>
    import Navigation from './_components/Navigation.svelte';
</script>

<!--TABS-->

<Navigation/>

pages/_components/Navigation.svelte


<script>
  import {isActive, url} from '@sveltech/routify'

  const links =
  [
    ['./index', 'Home'], //add index if you don't want siblings to be considered children
    ['./form', 'Form']
  ]
</script>

<style>
  .active {font-weight: bold}
</style>

<ul>
  {#each links as [path, name]}
    <!-- Svelte magic. If isActive is true, the "active" class is applied. -->
    <li class:active={$isActive(path)}>
      <a href={$url(path)}>
        {name}
      </a>
    </li>
  {/each}
</ul>

The navigation links appear but the problem now is that the content of the selected page does not appear.

In the image below, the form endpoint is being rendered. The form component has working HTML but the HTML does not appear on the page.

I am also getting a warning my my developer tools that says: " received an unexpected slot "default"

enter image description here


Solution

  • You shouldn't import your Navigation component into the index.svelte file but instead into a _layout.svelte file in the same directory.

    They show the setup in the TV Shows App and although they don't show the above code imported in a Nav file like you're trying it will work if the component with the above code is imported in the _layout file since the url helper resolves paths relative to the page/layout in which it's used.

    Importing it into the index file creates paths relative to the index file which is why you're seeing index in all routes.

    UPDATE:

    In response to needing to render the content of each page. This is done using a slot in the _layout file, in your example it would look like this:

    <Navigation/>
    
    <main>
      <slot />
    </main>