npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@auaust/inertia-adapter-solid

v0.4.2

Published

A better maintained fork of the SolidJS adapter for Inertia.js

Downloads

50

Readme

Inertia SolidJS Adapter

An adapter to bring SolidJS compatibility to systems using InertiaJS.

Installation

# Using NPM
npm install -D solid-js vite-plugin-solid inertia-adapter-solid

# Using Yarn
yarn add -D solid-js vite-plugin-solid inertia-adapter-solid

# Using PNPM
pnpm add -D solid-js vite-plugin-solid inertia-adapter-solid

Setup Vite

In your vite.config.js file, you will need to add the SolidJS plugin if not done already.

  import { defineConfig } from 'vite'
+ import solid from 'vite-plugin-solid'

  export default defineConfig({
      plugins: [
          laravel({
              input: ['resources/css/app.css', 'resources/js/app.js'],
              refresh: true,
          }),
+         solid(),
          // ...
      ]
  })

Initialize the Inertia app

Next, update your main JavaScript file to boot your Inertia app. To accomplish this, we'll initialize SolidJS with the base Inertia component.

import { createInertiaApp } from "inertia-adapter-solid";
import { render } from "solid-js/web";

createInertiaApp({
  resolve(name) {
    const pages = import.meta.glob("./Pages/**/*.jsx", { eager: true });
    return pages[`./Pages/${name}.jsx`];
  },
  setup({ el, App, props }) {
    render(() => <App {...props} />, el);
  },
});

Defining a root element

By default, Inertia assumes that yoru application's root template has a root element with an id of app. If your application's root element has a different id, you can provide it using the id property.

createInertiaApp({
  id: "my-app",
  // ...
});

Code splitting

Vite enables code splitting (or lazy-loading as they call it) by default when using their import.meta.glob() function, so simply omit the { eager: true } option, or set it to false, to disable eager loading.

- const pages = import.meta.glob('./Pages/**/*.jsx', { eager: true })
- return pages[`./Pages/${name}.jsx`]
+ const pages = import.meta.glob('./Pages/**/*.jsx')
+ return pages[`./Pages/${name}.jsx`]()

Pages

Inertia pages are simply SolidJS components, you will feel right at home.

import Layout from './Layout'
import { Title } from '@solidjs/meta'

export default function Welcome(props) {
  const user () => props.user

  return (
    <Layout>
        <Title>Welcome</Title>
        <h1>Welcome</h1>
        <p>Hello {user().name}, welcome to your first Inertia app!</p>
    </Layout>
  )
}

Creating Layouts

While not required, for most projects it makes sense to create a site layout that all of your pages can extend. You may have noticed in our example above that we're wrapping the page content within a <Layout> component. Here's an example of such component:

import { Link } from "inertia-adapter-solid";

export default function Layout(props) {
  return (
    <main>
      <header>
        <Link href="/">Home</Link>
        <Link href="/about">About</Link>
        <Link href="/contact">Contact</Link>
      </header>
      <article>{props.children}</article>
    </main>
  );
}

As you can see, this is a typical Solid component.

Persistent Layouts

While it's simple to implement layouts as children of page components, it forces the layout instance to be destroyed and recreated between visits. This means that you cannot have persistent layout state when navigating between pages.

For example, maybe you have an audio player on a podcast website that you want to continue playinh as users navigate the site. Or, maybe, you simply want to maintain the scroll position in your sidebar navigation between page visits. In these situations, the solution is to leverage Inertia's persistent layouts.

import Layout from './Layout'
import { Title } from '@solidjs/meta'

export default function Welcome(props) {
  const user () => props.user

  return (
    <>
        <Title>Welcome</Title>
        <h1>Welcome</h1>
        <p>Hello {user().name}, welcome to your first Inertia app!</p>
    </>
  )
}

Welcome.layout = Layout

Alternatively, you can also stack multiple layouts on top of each other.

import SiteLayout from './SiteLayout'
import NestedLayout from './NestedLayout'
import { Title } from '@solidjs/meta'

export default function Welcome(props) {
  const user () => props.user

  return (
    <>
        <Title>Welcome</Title>
        <h1>Welcome</h1>
        <p>Hello {user().name}, welcome to your first Inertia app!</p>
    </>
  )
}

Welcome.layout = [SiteLayout, NestedLayout]

You can also create more complex layout arrangements using nested layouts.

import Layout from './Layout'
import { Title } from '@solidjs/meta'

export default function Welcome(props) {
  const user () => props.user

  return (
    <Layout>
        <Title>Welcome</Title>
        <h1>Welcome</h1>
        <p>Hello {user().name}, welcome to your first Inertia app!</p>
    </Layout>
  )
}

Welcome.layout = (props) => {
  <SiteLayout title="Welcome">
    <NestedLayout>
      {props.children}
    </NestedLayout>
  </SiteLayout>
}

Props

Updating props

The page props are a Solid mutable. This means they are settable in a reactive way.

function Welcome(props) {
  return (
    <>
      Hello, {props.user.name}
      <button onClick={() => (props.user.name = "John Doe")}>
        Change name
      </button>
    </>
  );
}

It is best avoided to mutate the props directly from the frontend, but is sometimes useful when server endpoints are fetched to get additional data or update a specific part of the props, where using the only option isn't enough. Uses cases for this could be:

  • When paginating through a list of items. You can make a get request, and manually append the new items to the existing props.
  • Modifying a simple state, i.e. a wishlist/liked boolean on a product. Instead of returning the whole page again, the endpoint can return the new status of the product, and you can update the props directly.

Using a mutable rather than a store allows for direct assignment of the new value, instead of being forced to know the fully qualified path of the value you want to update along with the store setter function.

### Updated props persistence

Frontend updated props are persisted in the history only. This means you can update the props, move away and return to the same page and the state will be the same as when you left. However, it won't persist a page reload. This is mostly aimed to allow for optimistic updates, i.e. updating a prop knowing that the backend will persist the change or manually updating a specific part of the props based on the returned data from an endpoint.

Title & Metadata

This adapter brings compatibility to Meta-tags using @solidjs/meta official package, working in both Client-side Rendering and Server-side Rendering.

import { Title, Meta } from '@solidjs/meta'

<>
  <Title>Your page title</Title>
  <Meta name="description" content="Your page description" />
</>

Server-side Rendering (SSR)

Server-side rendering pre-renders your JavaScript pages on the server, allowing your visitors to receive fully rendered HTML when they visit your application. Since fully rendered HTML is served by your application, it's also easier for search engines to index your site.

Warning Server-side rendering uses Node.js to render your pages in a background process; therefore, Node must be available on your server for server-side rendering to function properly.

Note For this adapter, no additional dependencies are required.

Add server entry-point

Create a resources/js/ssr.js file whitin your Laravel project that will serve as the SSR entry point.

touch resources/js/ssr.js

This file is going to look very similar to your resources/js/app.js file, except it's not going to run in the browser, but rather in Node.js. Here's a complete example.

import { createInertiaApp } from "inertia-adapter-solid";
import createServer from "inertia-adapter-solid/server";

createServer((page) =>
  createInertiaApp({
    page,
    resolve(name) {
      const pages = import.meta.glob("./Pages/**/*.jsx", { eager: true });
      return pages[`./Pages/${name}.jsx`];
    },
  })
);

Client-side Hydration

Since your website will now be server-side rendered, you can instruct SolidJS to "hydrate" the static markup and make it interactive instead of re-rendering all the HTML that we just generated.

  import { createInertiaApp } from 'inertia-adapter-solid'
- import { render } from 'solid-js/web'
+ import { hydrate } from 'solid-js/web'

  createInertiaApp({
      resolve(name) {
          const pages = import.meta.glob('./Pages/**/*.jsx', { eager: true })
          return pages[`./Pages/${name}.jsx`]
      },
      setup({ el, App, props }) {
-         render(() => <App {...props} />, el)
+         hydrate(() => <App {...props} />, el)
      },
  })

Setup Vite

Next, we need to update our Vite configuration to build our new ssr.js file. We can do this by adding a ssr property to Laravel's Vite plugin configuration in our vite.config.js file.

  export default defineConfig({
      plugins: [
          laravel({
              input: ['resources/css/app.css', 'resources/js/app.js'],
+             ssr: 'resources/js/ssr.js',
              refresh: true,
          }),
-         solid(),
+         solid({ ssr: true }),
          // ...
      ],
  })

Update build script

Next, let's update the build script in our pacakge.json file to also build our new ssr.js file.

  "scripts" {
      "dev": "vite",
-     "build": "vite build"
+     "build": "vite build && vite build --ssr"
  }

Now you can build both your client-side and server-side bundles.

# Using NPM
npm run build

# Using Yarn
yarn build

# Using PNPM
pnpm build

Next steps

You can read the full documentation on Server-side Rendering on InertiaJS's Offial Guide.