0

I'm doing a SPA in Svelte. It works locally and on Svelte REPL where the component inside the condition is shown but not when I deploy to Gitlab Pages.

  # .gitlab-ci.yml
  script:
    - npm install
    - npm run build

In my App.svelte I use a svelte:component to always render the current $screen and only the footer component if the screen is Payments

<script>
    import { screen } from '../store.js' // current screen: Login, Profile, etc
    import Login from './Login.svelte'
    import Menu from '../components/Menu.svelte'

    // Screens with Menu
    const screens_menu = ['Payments']

    // Default screen
    $screen = Login
</script>

<main>
    <svelte:component this={$screen} />
    {#if screens_menu.includes($screen.name)}
        <footer><Menu /></footer>
    {/if}
</main>

In my store.js I have this

import { writable } from 'svelte/store'
// Current Screen
export let screen = writable(null)

Check same example

Working on Svelte REPL.

Note

If I use the component screen itself instead of the variable name everything works as expected but now (probably) I'm overloading (importing all the screens). Now, it's only Payments but it could be more screens.

<script>
    import { screen } from '../store.js'
    import Payments from './Payments.svelte'
    import Menu from '../components/Menu.svelte'
    
    // Screens with Menu
    const screens_menu = [Payments]
    // ...
</script>

<main>
    <svelte:component this={$screen} />
    {#if screens_menu.includes($screen)}
        <footer><Menu /></footer>
    {/if}
</main>

Do I need to configure anything extra, anyone experimenting something similiar after deployment?

Any help will be really appreciated :)

gengns
  • 1,573
  • 14
  • 23
  • There's no difference in what you're loading with $screen vs $screen.name. How is your store created? What's in store.js? – rixo Oct 21 '20 at 15:30
  • Thanks rixo, I've updated my question with `store.js`. I mean loading (importing) each screen/page that has a menu to do the check. Ex: with `const screens_menu = [Payments, Profile, Map, About]` I need to import but with `const screens_menu = ['Payments', 'Profile', 'Map', 'About']` I don't, I just check `$screen.name` – gengns Oct 21 '20 at 15:54

2 Answers2

0

If your store is defined as writable(null), it seems expected to me that you have to guard against the condition where the store's value is null.

Said otherwise, you should probably write your condition like such:

    {#if $screen && screens_menu.includes($screen.name)}
        <footer><Menu /></footer>
    {/if}
rixo
  • 23,815
  • 4
  • 63
  • 68
  • In that case it wouldn't be possible to render `` in first place. The error would jump the line before. I'm setting with a router `$screen = Login`. The thing is that it works locally but not when I deploy on Gitlab Pages. I've updated my question with the router. – gengns Oct 21 '20 at 22:11
  • `` supports being given a null value : see [this REPL](https://svelte.dev/repl/c6fbc997bc7c493287703e999582e56d?version=3.29.0). Apparently you've got a render cycle where `$screen` is null with the build version, somehow. Just avoiding to crash on this should make it work. Have you tried my suggestion? – rixo Oct 22 '20 at 15:47
  • Thank you so much rixo, yes I did but unfortunately it doesn't work. I have added [this working REPL](https://svelte.dev/repl/4f9a95802d6c43b39b4bdf4ff4a6b1f4?version=3.29.4) to my question and the [same code](https://gitlab.com/gengns/svelte-gitlab-pages) to [a not working Gitlab Page example](https://gengns.gitlab.io/svelte-gitlab-pages/) where the footer is not shown. – gengns Oct 26 '20 at 01:22
0

$screen.name after deployment has changed because of the internal refactoring (bundling). Therefore the condition is never met and the Menu never shown.

Relying on a function's name in any app - Svelte or not - is a bad idea because can be affected by bundling.

Finally, as proposed in my question, I'm using the components instead of the names. Maybe thanks to tree-shaking there is no overloading.

gengns
  • 1,573
  • 14
  • 23