solid-start icon indicating copy to clipboard operation
solid-start copied to clipboard

`ssr: false` has no effect?

Open stereobooster opened this issue 3 years ago • 6 comments

I'm new to this lib, so maybe I don't understand something. I have

export default defineConfig({
  plugins: [solid({ ssr: false })],
});

But components still render on the server. I get this error

An error occured while server rendering /:

	window is not defined

stereobooster avatar Dec 05 '22 19:12 stereobooster

I encountered this as well. What I eventually ended up doing is:

if (typeof window === 'undefined') {

...which is a way to test for the existence of window without getting a dereference error.

viridia avatar Dec 05 '22 22:12 viridia

Setting SSR to false does mean that CSR would be used as far as I know. So it probably still runs the SSR but doesn't use it.

orenelbaum avatar Dec 05 '22 22:12 orenelbaum

which is a way to test for the existence of window without getting a dereference error.

Yes I know how typeof works. I could as well do

import { isServer } from "solid-js/web";

if (!isServer) ...

I'm not looking for workaround. I just think it's counterintuitive

stereobooster avatar Dec 05 '22 23:12 stereobooster

It's definitely something that needs to be solved even if there's an easy workaround.

orenelbaum avatar Dec 05 '22 23:12 orenelbaum

Interesting observation - only module scope code is run on the server. I think that it has to do with a Babel plugin Solid Start runs.

orenelbaum avatar Dec 06 '22 15:12 orenelbaum

I want to add that this only happens in development mode. When you generate a production build, it actually builds CSR and all those SSR errors disappear.

But anyway, it's annoying because you have to wrap things with isServer just to make sure the dev environment works.

Vexcited avatar Dec 07 '22 22:12 Vexcited

I'm getting the "window is not defined" from within the pikaday.js calendar library, which I'm using in a Solid Component. (SolidStart, with a bare template and SSR no, and tailwind)

The Component, DateForm is as follows...

import { createSignal, onMount } from "solid-js"
import Pikaday from 'pikaday'

export function DateForm() {

  const [formDt, setFormDt] = createSignal("")

  onMount(() => {
    const pika = new Pikaday({
      field: document.getElementById('formpika'),
      onSelect: function(dt) {
        setFormDt(pika.toString())
      }
    })
  })

  return (
    <>
      <div class="flex flex-col max-w-screen-md">
        <div class="flex flex-col items-center justify-center">
          Hello, choose date:
        </div>
        <div>
          <div>Date: { formDt }</div>
          <input type="text" id="formpika" />
        </div>
      </div>
    </>
  )
}

The window usage is within pikaday. Is there pehaps a work around to get and set a window reference, before calling pikaday?

adriancu avatar Dec 23 '22 15:12 adriancu

Try to use a dynamic import inside the onMount like const Pikaday = await import("pikaday");.

Vexcited avatar Dec 23 '22 16:12 Vexcited

Thanks, I tried the dynamic import, but for anywhere within the scope of onMount( ... ), I get a compile error "Unexpected reserved word 'await'". I tried the await import inside my arrow function above, and also as a separate function outside the Component (as below). Moving it to module scope, the await import compiles, but we get the missing window reference error again.

import { createSignal, onMount } from "solid-js"

const [formDt, setFormDt] = createSignal("")

//const imp = await import('pikaday')    // <-- done here compiles but gives the window reference error
//const Pikaday = imp.default

const setupPika = function() {
    const imp = await import('pikaday')    // <--- compile error
    let Pikaday = imp.default
    let pika = new Pikaday({
    field: document.getElementById('formpika'),
      onSelect: function(dt) {
      Say("in onSelect...X "+pika.toString())
      setFormDt(pika.toString())
    }
  })
}
export function DateForm() {
  onMount( setupPika )
// ... etc
}

adriancu avatar Dec 24 '22 05:12 adriancu

That's just because the function needs to be async

onMount(async () => {
  const Pikaday = await import ("pikaday");
  // your code...
});

Vexcited avatar Dec 24 '22 08:12 Vexcited

BTW this seems like a bug, not a question

orenelbaum avatar Dec 24 '22 09:12 orenelbaum

@Vexcited, thanks! Worked with a properly formed async/await :). For the benefit of others who may come across this, here's the working code:

export default function DateForm() {

  onMount( async () => {
    const imp = await import('pikaday')
    const Pikaday = imp.default

    const pika = new Pikaday({
      field: document.getElementById('formpika'),
      onSelect: function(dt) {
        setFormDt(pika.toString())
      }
    })
  })

  return (
    <>
      <div class="flex flex-col max-w-screen-md">
        <div class="flex flex-col items-center justify-center">
          Hello, choose date:
        </div>
        <div>
          <div>Date: { formDt }</div>
          <input type="text" id="formpika" />
        </div>
      </div>
    </>
  )
}

adriancu avatar Dec 24 '22 11:12 adriancu

Retry this in 0.2.19. Hopefully this is fixed.

ryansolid avatar Feb 03 '23 06:02 ryansolid

In setting up for SolidStarts next Beta Phase built on Nitro and Vinxi we are closing all PRs/Issues that will not be merged due to the system changing. If you feel your issue was closed in mistake. Feel free to re-open it after updating/testing against 0.4.x release. Thank you for your patience.

See https://github.com/solidjs/solid-start/pull/1139 for more details.

ryansolid avatar Dec 18 '23 23:12 ryansolid