Skip to content

Fix various TypeScript issues, simplify ziggy-js integration and shared props usage #127

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

Merged
merged 12 commits into from
Jun 5, 2025

Conversation

TimKunze96
Copy link
Contributor

This pull request simplifies type usage, removes unused imports, and improves the SSR setup.

Ziggy-JS

While following the Ziggy-JS setup guide, I noticed that our ssr.ts file does a lot of unnecessary work. We can replace most of it with the ziggyVue plugin. We also don’t need the Ziggy alias pointing to the vendor directory, since Ziggy is already installed as a JS dependency. Finally, I added proper Vue-specific route definitions.

TypeScript Types

  • SharedProps: Refactored to extend and override the package’s App props, so we can use the usePage helper without manually declaring prop types each time.
  • Inertia helpers: Added missing type definitions for Inertia helper functions used in template files.
  • tsconfig.json: Removed the non-existent vue/tsx entry from the types array. It wasn’t provided by any installed package and caused errors during vue-tsc type checks.

@TimKunze96
Copy link
Contributor Author

Continuation of #87

@Plytas
Copy link

Plytas commented Apr 24, 2025

Maybe we should go ahead and use wayfinder instead of ziggy?

@TimKunze96
Copy link
Contributor Author

I plan to switch to Wayfinder once it’s stable, but given Ziggy’s long history of being preconfigured in the starter kits, I think it should remain available—perhaps as an install-time option?

@Ciaro
Copy link
Contributor

Ciaro commented Apr 24, 2025

Thanks for this, Tim! While we are on the subject of Ziggy: is there a specific reason why all the Ziggy routes are a part of the Inertia shared data as well? The routes are already part of the page via the global Vue configuration, no?

@TimKunze96
Copy link
Contributor Author

TimKunze96 commented Apr 24, 2025

As I understand it, this is necessary because the SSR script doesn’t have access to the Blade file’s contents. When the server renderer tries to read the routes that the Blade file would normally declare, it fails. The client-side script works fine, however, because by the time it executes, the routes have already been declared and are available in the browser.

That’s why we need to pass the routes via shared properties. Technically, this should only be necessary in the initial, server-rendered response. If an X-Inertia header is present on subsequent requests, we could skip that step, if I’m not mistaken.

This discrepancy has been a real pain point for me in the past—SSR errors (for example, accessing document or window) are easy to overlook during development if the client-side script still runs without issue.

Edit: While digging a little bit deeper I stumbled across those posts, basically all outlining the same problem:

https://github.com/tighten/ziggy/discussions?discussions_q=is%3Aopen+ssr

This post basically ends up with what we have now I believe
tighten/ziggy#564

@Ciaro
Copy link
Contributor

Ciaro commented Apr 25, 2025

Really appreciate the thorough explanation, Tim!

I won't be using SSR any time soon, so I just removed the sharing of the Ziggy routes in Inertia and replaced the one reference to it (resources\js\layouts\settings\Layout.vue) with a reference to the page.url parameter Inertia already exposes:

const currentPath = new URL(page.props.location).pathname;

becomes:

const page = usePage();
currentPath = page.url;

@tnylea tnylea added the Additional Testing in Progress Needs more testing or waiting until we can add this feature to all starter kits label Apr 25, 2025
@danbarbarito
Copy link

Would love to see this merged

@taylorotwell taylorotwell merged commit c17ef70 into laravel:main Jun 5, 2025
2 checks passed
@bdlowery
Copy link

bdlowery commented Jun 7, 2025

This will not work if you use route() in a composable, like so:

import { ref, watch } from 'vue';
import { usePage } from '@inertiajs/vue3';

export function useActiveRoute(routeName) {
    const isActive = ref(route().current() === routeName);
    const page = usePage();

    watch(
        () => page.url,
        () => {
            isActive.value = route().current() === routeName;
        },
    );

    return isActive;
}

The old implementation with

 // Make route function available globally for SSR...
            if (typeof window === 'undefined') {
                global.route = route;
            }

Accounted for that allowing route() to work in a composable.

@TimKunze96
Copy link
Contributor Author

TimKunze96 commented Jun 8, 2025

Yes, according to the ziggy documentation you are supposed to inject the route function if you want to use it within a <script setup block. I usually create my own route composable. that just does that, it looks similar to this:

import { route } from 'ziggy-js';
import { inject } from 'vue'

type Router = typeof route;

function useRoute(): Router {
    const route = inject<Router>('route');

    if (!route) {
        throw new Error('Route context is not provided. Make sure that the ZiggyVue plugin is properly installed and configured.');
    }

    return route;
}

// .. in another composable

export function useSomething() {
    const route = useRoute();

    // Example usage of the route function
    const currentRoute = route().current();
}

@TimKunze96
Copy link
Contributor Author

I decided to create a pull request for the useRoute composeable #151

@bdlowery
Copy link

bdlowery commented Jun 11, 2025

That's actually pretty smart, thank you. I wish something like this was included on the Inertia docs, especially since ziggy is so tightly coupled with Inertia and Laravel. It caused a lot of confusion on our end when trying to do SSR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Additional Testing in Progress Needs more testing or waiting until we can add this feature to all starter kits
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants