Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

svelte-kit package cannot include goto function from $app/navigation #3010

Closed
vpanyushenko opened this issue Dec 9, 2021 · 7 comments
Closed
Labels
documentation Improvements or additions to documentation pkg:svelte-package Issues related to svelte-package
Milestone

Comments

@vpanyushenko
Copy link

Describe the bug

When creating a component library with Svelte Kit and packaging it using svelte-kit package, you cannot include other functions, specificlly tested with goto.

One of my components that will be exported was using the goto function from kit. It was a select element that modified a url query parameter, and then used the goto function to rerun the load function. Everything works just fine in dev. I import the Select component I created into my project.

However, when the app is build and I run svelte-kit preview, the goto function no longer works. Both the one in my exported package and the one that I import on the page as well.

The error I get is: TypeError: Cannot read properties of undefined (reading 'goto'). Again this only happens after everything is built.

Reproduction

I created a button UI component using goto for a simple example

<script>
  import { goto } from "$app/navigation";

  export let label = "Button Label";
  export let href;
</script>

<button
  on:click={(event) => {
    console.log(event);
    console.log("Svelte goto button test");
    goto(href)
      .then(() => {
        console.log("Page navigated successfully");
      })
      .catch((err) => {
        console.error(err);
      });
  }}
>
  {label}
</button>

I exported it correctly and published the package on npm, the library is called svelte-kit-goto-test

Next I installed the library as a dependency in my project, imported the Button. The home link used the Button component and the about link uses the imported goto component:

<script>
  import { goto } from "$app/navigation";
  import { page } from "$app/stores";
  import logo from "./svelte-logo.svg";
  import { Button } from "svelte-kit-goto-test"; //imported component
</script>

<header>
  <div class="corner">
    <a href="https://kit.svelte.dev">
      <img src={logo} alt="SvelteKit" />
    </a>
  </div>

  <nav>
    <svg viewBox="0 0 2 3" aria-hidden="true">
      <path d="M0,0 L1,2 C1.5,3 1.5,3 2,3 L2,0 Z" />
    </svg>
    <ul>
      <li class:active={$page.path === "/"}>
        <Button label="Home" href="/" /> 
      </li>
      <li class:active={$page.path === "/about"}>
        <button
          on:click={() => {
            goto("/about")
              .then(() => {
                console.log("Success");
              })
              .catch((err) => {
                console.error(err);
              });
          }}>About</button
        >
      </li>
    </ul>
    <svg viewBox="0 0 2 3" aria-hidden="true">
      <path d="M0,0 L0,3 C0.5,3 0.5,3 1,2 L2,0 Z" />
    </svg>
  </nav>

  <div class="corner">
    <!-- TODO put something else here? github link? -->
  </div>
</header>

When previewing with svelte-kit dev, the navigation works as expected. When building the project and using svelte-kit preview, the links don't work and we get the error TypeError: Cannot read properties of undefined (reading 'goto') at Lt (vendor-ae893024.js:1) at HTMLButtonElement.<anonymous> (__layout.svelte-6aa37c4a.js:1)

I deployed a version with the issue: https://svelte-kit-goto-test.vercel.app/

Here the github repo: https://github.com/vpanyushenko/svelte-kit-goto-test

Logs

No response

System Info

Tested with Chrome, Firefox, and Safari

Severity

serious, but I can work around it

Additional Information

Currently removed the goto links from the library and using window.location which isn't ideal but works.

I'm guessing this has to to with the package only including files from $lib but I don't quite understand how this works. If this is a feature, not a bug, does this mean that the libraries cannot use any of the svelte kit utility functions?

@bluwy
Copy link
Member

bluwy commented Dec 9, 2021

Yes you're right. SvelteKit utility functions can't be used for packaging as your library can be used for non-SvelteKit projects too. The utilities also requires to be directly imported (instead of from a package) so it is expected behaviour that it doesn't work. Perhaps we can document this though.

@bluwy bluwy added documentation Improvements or additions to documentation pkg:svelte-package Issues related to svelte-package labels Dec 9, 2021
@vpanyushenko
Copy link
Author

If we're using a lot of svelte specific features in the library like sveltekit:prefetch and the dynamic classes, are those compatible with other non-svelte kit projects after the build step?

I guess a workaround for the use case I described is to pass in the utility function as a prop to the component, though it will lock people into using svelte kit.

@bluwy
Copy link
Member

bluwy commented Dec 9, 2021

svelteKit:prefetch won't work in a non-SvelteKit project either. Ideally your components should be as "dumb" as possible so it can be used generically in different projects. It shouldn't make any assumptions about routing and the environment used.

For sveltekit:prefetch, you could use $$restProps on your component and let the consumer decide whether to add the prefetch or not. For goto, your component could dispatch an event and let the consumer route itself.

@vpanyushenko
Copy link
Author

I totally see where you're coming from and I see the benefits of doing it that way. Especially for folks who want to make packages for non-svelte projects.

However, I also see the benefits of making libraries and components specifically for svelte kit projects that let developers get all the nice sveltey things if they are invested in the ecosystem like element and component directives out of the box. I feel like that's already 80% possible without being about to access the utility functions.

But I'm biased and heavily invested in the ecosystem and could very well be the odd man out here.

@dummdidumm
Copy link
Member

Honestly I feel the same, ideally this is possible somehow, but I don't know how we could achieve this right now.

@jycouet
Copy link
Contributor

jycouet commented Jul 20, 2022

Maybe on a svelte-kit package there could be an option: --for_svelte-kit_only ?
Like this, you can do different levels of libraries?

@benmccann
Copy link
Member

Closing as duplicate of #1485

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation pkg:svelte-package Issues related to svelte-package
Projects
None yet
Development

No branches or pull requests

6 participants