Coder Social home page Coder Social logo

inertiajs / inertia Goto Github PK

View Code? Open in Web Editor NEW
5.8K 5.8K 391.0 1.79 MB

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers.

Home Page: https://inertiajs.com

License: MIT License

JavaScript 26.65% Svelte 1.50% Vue 12.69% HTML 0.04% TypeScript 14.53% PHP 44.43% Blade 0.14% CSS 0.03%

inertia's Introduction

Inertia.js

Inertia.js lets you quickly build modern single-page React, Vue and Svelte apps using classic server-side routing and controllers. Find full documentation at inertiajs.com.

Contributing

If you're interested in contributing to Inertia.js, please read our contributing guide.

Sponsors

A huge thanks to all our sponsors who help push Inertia.js development forward! In particular, we'd like to say a special thank you to our partners:

Laravel Forge

If you'd like to become a sponsor, please see here for more information. ๐Ÿ’œ

inertia's People

Contributors

adrianmrn avatar anubra266 avatar bloemendaal avatar bradlc avatar claudiodekker avatar craigrileyuk avatar davecodes1 avatar dependabot[bot] avatar driesvints avatar guihigashi avatar hailwood avatar innocenzi avatar jaulz avatar jessarcher avatar kasperstyre avatar lucared avatar lumore avatar mariojankovic avatar michaeldeboey avatar pedroborges avatar reinink avatar robertboes avatar rovansteen avatar sebastiandedeyne avatar spice-king avatar stephensamra avatar tofandel avatar wazum avatar ycs77 avatar zlokomatic avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

inertia's Issues

[inertia-vue] Incorrect typings

I'm using @inertiajs/inertia 0.1.4 and @inertiajs/inertia-vue 0.1.2.
I'm refactoring my app using TypeScript, but I got this error as soon as I enabled TypeScript linting in my main file:

Error message
No overload matches this call.
  Overload 1 of 2, '(plugin: PluginObject<unknown> | PluginFunction<unknown>, options?: unknown): VueConstructor<Vue>', gave the following error.
    Argument of type 'Component<AppData<PageProps>, never, never, AppProps<PagePropsBeforeTransform, PageProps>>' is not assignable to parameter of type 'PluginObject<unknown> | PluginFunction<unknown>'.
      Type 'VueConstructor<Vue>' is not assignable to type 'PluginObject<unknown> | PluginFunction<unknown>'.
        Property 'install' is missing in type 'VueConstructor<Vue>' but required in type 'PluginObject<unknown>'.
  Overload 2 of 2, '(plugin: PluginObject<any> | PluginFunction<any>, ...options: any[]): VueConstructor<Vue>', gave the following error.
    Argument of type 'Component<AppData<PageProps>, never, never, AppProps<PagePropsBeforeTransform, PageProps>>' is not assignable to parameter of type 'PluginObject<any> | PluginFunction<any>'.
      Type 'VueConstructor<Vue>' is not assignable to type 'PluginObject<any> | PluginFunction<any>'.
        Property 'install' is missing in type 'VueConstructor<Vue>' but required in type 'PluginObject<any>'.

I believe the typings may be incorrect?

Refactor to only named exports

My suggestion is to refactor both core and adapters to only have named exports.

I came across this article, when I started looking what's most used in the community.
When I looked into the React community I came across well know libraries which were 50-50 divided in the use of only named exports or having a default export too.

Only named:

Default export too:

But when looking a bit closer, It stood out to me that the libraries that expose nestable components, only have named exports.

Since InertiaLink is something that needs te be nested in Inertia[Adapter] (just like Link is nested in a Router f.i.), my suggestion is to update all current packages to only export named exports.

This too has the advantage that it will maybe (don't know for sure) be easier to refactor the typings in a more modern way without the use of modules.

Like I said before: I only looked into the React community to see what's commonly used, but I think that if we do it for one of the packages, we should do it for all of them to be consistent.

Consider caching page history instead of reloading

WIP branch: history-state

Currently, when traversing the history in an Inertia app, each page is reloaded. Meaning, a new Inertia request is made to the endpoint, and then the page is shown.

One one hand this is nice, since you always get the current, most up-to-date content. However, it's not really how the web works by default. When you traverse history in a standard server-side rendered app, you see the previously loaded from cache. It's not reloaded. To do that you have to hit refresh.

Further, since each page is being reloaded via ajax, there is a delay while waiting for those requests. Generally this isn't an issue, but on iOS it definitely is (see #5).

I want to revisit caching each page visit in history state. One one hand this easy. After each Inertia visit, we simply grab the response and put it into history. The problem is when changes are made to the page. Those state changes not saved, since they happen after we've already updated the history state. Ideally we'd update the history state before navigating away, but this isn't really possible, since we don't have insight into the internal, local state of the page component. All we have is the response data (props).

One idea I am considering is a way to manually update the history state when the component state changes. For example, consider an edit organization page that has a form containing all the fields. We could setup a watcher to catch state changes:

watch: {
  form: {
    handler: () => Inertia.state('organization', this.form),
    deep: true,
  },
},

Basically you just give Inertia.state() a key/value pair that automatically replaces (merges?) the current page history state.

Alternatively, it would be cool to attach this directly to the page component data. Something like this:

data() {
  return {
    form: Inertia.state('organization', {
      name: this.organization.name,
      email: this.organization.email,
      phone: this.organization.phone,
      address: this.organization.address,
      city: this.organization.city,
      region: this.organization.region,
      country: this.organization.country,
      postal_code: this.organization.postal_code,
    }),
  }
},

Not really sure if that's possible, while keeping everything reactive, but I think it's worth exploring. The key with Inertia.state() is that it wouldn't return state from that function call, it would just update the history state. That history state would be automatically "applied" to the page component as a prop when it's reloaded (during a history visit).

Implement a middleware pipeline

A middleware pipeline could potentially clean things up internally and make the package a lot more extendible.

A few usage examples:

  • Pretty much everything in visit could be moved to a middleware, making inertia.js a lot lighter
  • Refactor transformProp to a middleware
  • Allows users to hijack the request/response cycle (as requested in #73)
  • Could be used to implement loading indicators (#9)
  • Could be used to hijack the request for previsits (#45)

Manually making visits

Inertia-Vue github repo has a section called Manually Making Visits which is missing on the document.

In addition to clicking links, it's also very common to manually make Inertia visits. The following methods are available. Take note of the defaults.

$inertia.visit(url, { method: 'get', data: {}, replace: false, preserveScroll: false, preserveState: false })
$inertia.replace(url, { method: 'get', data: {}, preserveScroll: false, preserveState: true })
$inertia.reload({ method: 'get', data: {}, preserveScroll: false, preserveState: false })
$inertia.post(url, data, { replace: false, preserveScroll: false, preserveState: true })
$inertia.put(url, data, { replace: false, preserveScroll: false, preserveState: true })
$inertia.patch(url, data, { replace: false, preserveScroll: false, preserveState: true })
$inertia.delete(url, { replace: false, preserveScroll: false, preserveState: false })

Can someone please verify?

Thanks for an amazing library.
Rutvij

Preserve #id_of_element in route after redirection

Problem:
When inertia-link href attribute contains #some_id it is not preserved.

Example:
After click inertia-link with href="homepage#contact" it send us to //example.com/homepage, dropping "#contact" from url.

Expected behavior:
To keep #id in url and scroll to it's position after redirect

Hijack Inertia responses before they get applied

I'm working a team settings page, /teams/1/settings. It also has "Create team" button somewhere. That button opens a modal, which has a simple form that submits with Inertia. After that, the user gets redirected to /teams/2/settings, the new team's settings page.

I need preserveState: true on the form so the form errors are correctly displayed. No problems there.

However, since I'm preserving state, /teams/2/settings also has some "zombie state" from /teams/1/settings, like the modal that doesn't close or other form values that are incorrect.

This means I only know whether I want to preserve state or not based on the response.


I'm not sure what the correct solution for this problem would be. Modifying the preserveState value based on the response would solve this specific use case.

However, I've had other places where I wanted to do something after a visit based on the response, and maybe hijack Inertia's behaviour. Something generic like #44 could solve a broader set of problems. While I still stand by my original comment that it's not "idiomatic Inertia", it would be nice to have an escape hatch.

Reloading in Safari

Tested in Safari 12.03 & 12.1

The initial page loads fine, but when you refresh, it throws the following error:

"TypeError: undefined is not an object (evaluating 'window.performance.getEntriesByType("navigation")[0].type')"

I added a length check on the array in inertia.js line 28 and it seems to work. Happy to open a PR.

Page transitions: Fade

I'm trying to figure out how to apply a fade animation on component switching. Any idea how to get this done?

IE11 compatibility

I've been struggling to have Inertia and Inertia-vue working with IE11.

Is there an official browser support chart for Inertia?

The first issue I ran into was 'Promise is undefined', and once I managed to transpile it I'm just seeing a blank page with no errors.

Any ideas? Shouldn't this repo be transpiled before it's published to npm?

$page props in child components cause routing failure

I'm running into a hard-to-track issue where any usage of $page in components that are not at the top page level cause routing to malfunction. I've noticed that the error happens when conditionally displayed components are involved.

In my case, I have a Coupons page. It has a NewCouponForm component that is conditionally rendered based on if a button is clicked to create a new coupon. Inside that NewCouponForm component, I am accessing the $page store to get the type property.

Coupons.svelte:

<Layout title="Coupons">
  <div class="h-screen">
    <div class="text-center mt-6">
      <h2 class="text-4xl tracking-wide text-gray-800">Coupons</h2>
    </div>

    <div class="w-1/2 mx-auto mt-6">
      {#if showNewCouponForm}
        <NewCouponForm on:created={addNewCoupon} />
      {:else}
        <div class="flex justify-end">
          <button
            on:click|preventDefault={() => (showNewCouponForm = true)}
            class="bg-teal-500 text-white font-semibold hover:text-teal-700
            hover:bg-transparent py-1 px-2 border border-teal-500 rounded">
            Add New Coupon
          </button>
        </div>
      {/if}
    </div>

    <div class="w-1/2 mx-auto mt-8">

      {#each coupons as coupon}
        <div
          on:click={() => (selectedCouponId = coupon.id)}
          class="mt-8 first:mt-0 cursor-pointer">
          <Coupon
            bind:coupon
            {types}
            selected={selectedCouponId === coupon.id} />
        </div>
      {/each}

    </div>
  </div>
</Layout>

The NewCouponForm.svelte (child component) is fairly large, but it has this snippet:

<select
  bind:value={coupon.type}
  name="type"
  required
  id="coupon-{coupon.id}-type">
  {#each $page.types as type}
    <option value={type.key}>{type.description}</option>
  {/each}
</select>

As you can see, this NewCouponForm has a reference to $page. The page actually renders this just fine, and I like being able to access the global page store without having to pass props down.

The issue shows up when I try to navigate to a different page once I've clicked the button to create a new form. Since the NewCouponForm component was displayed, it accessed the $page.types value to use it in a dropdown. When I click on an InertiaLink in the navbar, the page does not transition. No console errors either.

If I visit the Coupons page but do NOT click on the button that shows the NewCouponForm, then I can navigate away just fine.

Once I changed my code to pass down the types as a prop, there were no issues. This isn't desired though since the store is supposed to be globally accessible.


I did my best to cover what I know about the issue, but it may not be expansive. Just let me know what questions you have. :)

Reloading with data duplicate query parameters

If I am on a /users?page=1 page, and I click on a button that does

Inertia.reload({
  data: {
    page: 1,
 }

I now see /users?page=1&page=1, and it keeps duplicating when I click again. Is this expected behaviour or is this a bug?

Lazy evaluation of preserveScroll and preserveState

This issue replaces #49

Sometims you don't know whether you want to preserve scroll or state until after you've recieved the response.

This could be solved by accepting closures that receive the response instead of plain boolean values.

Inertia.post('/teams/create', { 
  preserveState: page => Object.keys(page.errors).length, 
});

This would preserve the state of there are errors; or completely rerender if the form was succesfully submitted.

Add beforeVisit option to Inertia.visit and InertiaLink

I don't have an exact API for this yet, but here's the ideaโ€ฆ

It'd be nice to be able to do something before a visit (and potentially cancel the visit).

Something that comes up a lot is displaying a confirm modal before deleting something. We could render a modal in the beforeVisit call, and only do the visit after the user has confirmed.

<InertiaLink :href="`/posts/${post.id}`" method="DELETE" beforeVisit="confirm">
  Delete post
</InertiaLink>

This could get rid of unnecessary boilerplate in applications. I thought of this after a discussion with @michaeldyrynda on Discord.

Screenshot 2019-09-26 at 11 11 06

Screenshot 2019-09-26 at 11 10 57

Add option to disable Inertia Modal

Hey, I try to implement Inertia into a very large application. In the beginning I can only replace some parts of the app, so I run into the problem that I can't use <inertia-link /> there. It's because whenever I link into a legacy part of the app, the link will be opened in a modal. Since this is cool for something like error pages, it would be great to have an option to change that behavior. What do you think?

Dynamic imports and CSS extraction

I ran into an interesting problem today when building out an inertia app that might be worth sharing lest anyone else have the same problem. It's worth noting that none of what follows is an issue with Inertia itself, but as the recommended way of using Inertia is to implement dynamic imports, this info might prove useful, particularly for people using Laravel Mix.

Assuming you've followed along with with the 'standard' inertia set and you have dynamic imports working then you'll most likely find that you cannot use the extractVueStyles option in Laravel Mix. Took me a while to track this down but unfortunately this looks like an upstream limitation in webpack 4 (rather than a bug or missing feature of Mix) that should hopefully be fixed in webpack 5. Most of the info I gleaned was from this issue:
laravel-mix/laravel-mix#1856.

For my purposes, whilst CSS extraction would be nice, it's not a dealbreaker not to have it. It's worth noting that, contrary to the Mix docs, you apparently can use the globalVueStyles option in Mix without using the extractVueStyles. This is the case on recent versions of mix at least.

One last gotcha note is that, if you are using 'normal' css/sass/less/stylus in your single file component <style> block or if you are used 'scoped' css then things should work fine for you out of the box but if you are using CSS modules then you will (at time of writing) find that things don't work as expected.

I've not managed to solve this yet though the tip left in this comment might help get you on the right track: laravel-mix/laravel-mix#1930 (comment). This comment might well work if you are using plain CSS in your <style> block though I am using SCSS and I've not found a config that works correctly yet.

Another option that might help to circumvent some of these issues is to just not use dynamic imports with Inertia. I suspect that you could bypass this aspect of Inertia if you want though perhaps @reinink could help clarify whether dynamic imports are optional or not.

[inertia-vue] How to pass custom headers

Hi,

I see that $inertia uses axios internally and I have set global config for axios to pass in my auth header in every request.
Requests that are being made by axios respect that but those made by $inertia dont.
Can you please tell me if there a way around this?

I want to pass in my custom header in every request.

Use Inertia for 'none' Inertia Page Loads

We have two use cases where we need to use axios directly, because we load data async from api endpoints. We want to avoid using axios directly and use inertia for it.

1. File Uploads
We a list of files which will be uploaded asynchronously and attached to the form data as array of ids after successful upload.

2. Select fields
We have a lot of users in the database which we want to pick from a select field.

When we use inertia.post without setting the inertia header, the response data will be shown in the modal view. When we add the inertia header in the response the data will be applied to the setPage function.

The Solution
We includeheader['x-inertia'] in the response for those async non page endpoints,
which will solve the modal view problem.
We need a check if the payload data is an inertia page payload and return the data object if not.

inertia/src/inertia.js

Lines 86 to 90 in a515eae

}).then(page => {
if (page) {
this.setPage(page, visitId, replace, preserveScroll, preserveState)
}
})

Possible solution:

then(page => {
      if (page.version /* && page.component .. whatever is needed for the detection*/) {
        this.setPage(page, visitId, replace, preserveScroll, preserveState)
      } else {
        return page
      }
})

This change gives us the possibilty to access the returned data in then:

this.$inertia.post(..., formData).then((data) => {
//... do something with the data here.
})

final question
Is this change worst it?
Should we intergrate this behaviour to avoid the direct use of axios?

Slidely differnt solution to #44

TypeError: undefined has no properties

I'm testing inertia with Elixir/Phoenix and Preact. I'm getting an undefined error on this line: https://github.com/inertiajs/inertia/blob/a515eae3ba716c7773b994fb9850a613cb4f1a7/src/inertia.js#L101

The browser debugger it shows as:

setPage(page, visitId = undefined.createVisitId(), replace = false, preserveScroll = false, preserveState = false) {

This workaround worked for me:

  setPage(page, visitId = undefined, replace = false, preserveScroll = false, preserveState = false) {
    visitId = visitId || this.createVisitId();
    Progress.increment()

Edit:
I also tried removing node_modules and installing everything again with npm i. But I still get this error.
node version: 10.16.0
npm version: 6.9.0

Children components?

First of all, nice idea as always @reinink!
What do you think about going deeper and allowing to return children components from backend?

[inertia-vue] Listening to & intercepting visit (navigation) events

If you were to implement a feature like warning a user before exiting a page, how would you go about and implement this in Inertia?

If the user navigates back or clicks on a <inertia-link />, the "onbeforeunload" event is not actually called. When a user navigates back in history, the "popstate" event seems to be called indefinitely.

Are there any events that I can subscribe my listeners to?

Partial page reloads

Different sections of a page sometimes have different data requirements. For example a datatable with a set of dropdown filters: when you switch pages in the datatables, the dropdown data will also be refetched on the server. This isn't necessarily bad, but this can slow down your app with large datasets.

Ideally, there would be a way to tell Inertia which data you want changed, so it would only fetch and update subset of the page's data.

On the server, data would need to optionally be marked as potentially "lazy". In PHP/Laravel, the data could be wrapped in a callback:

class UsersController extends Controller
{
    public function index()
    {
        return Inertia::render('Users/Index', [
            'users' => Users::paginate(),
            'countries' => function () {
                return Country::all();
            }
        ]);
    }
}

(Sidenote: this only affects subsequent loads on the same page, the first visit will always fetch all of the page's necessary data)

On the client, you'd need to be able to specify which data you want to reload. In Vue:

this.$inertia.reload({ only: ['users'] });

This would send a request with an X-Inertia-Only header containing the users key, so Inertia can strip out the rest of the data on the server. The Country::all() database query would be completely skipped because it never gets evaluated.

When the request comes back, the new props will be merged with the old ones.


Kind of related to inertiajs/inertia-laravel#37

Thanks @reinink and @adamwathan for the feedback on this earlier ๐Ÿ’ช

Control Param serialization of get requests

We rely on json:api filtering and we use the wonderful querybuilder from spaite https://github.com/spatie/laravel-query-builder.
It would be helpful to have an option for the paramsSerializer function to pass to axios globally so we dont need to think about it.

Problem:
When we use a json:api conform get filter string (for example: filter[name]=mpociot), we cannot use the data object as implemented.

We cannot use the get params introduced by @mpociot with #28 , because the standard serialization of axios conflicts with json:api.

instead of:

 this.$inertia.get(url,form)

we have to use the url and encode with every request:

this.$inertia.get(url + Qs.Stringify(form, {
            encode: false,
            addQueryPrefix: true,
            filter: (prefix, value) => (value === "" ? undefined : value)
          })

When we allow to make use of:

//axios config (pass with each request)
paramsSerializer: function (params) {
    return Qs.stringify(params, {arrayFormat: 'brackets'})
},

we can use for my example:

paramsSerializer: function (params) {
    return Qs.Stringify(this.data(), {
            encode: false,
            addQueryPrefix: true,
            filter: (prefix, value) => (value === "" ? undefined : value)
          });
},

and apply it globally before the adapter is set up:

Inertia.paramsSerializer = function (params) { ... };

to make json:api conform request.

final question
Do we want to support this?
If yes i will provide a pr shortly.

Module parse failed: Unexpected token

I am using laravel mix versions 3

After updating the package to latest changes and trying to : "npm run dev"..
I got this error:

ERROR in ./node_modules/inertia/src/inertia.js
Module parse failed: Unexpected token (109:44)
You may need an appropriate loader to handle this file type.

replace(url, options = {}) {
 return this.visit(url, { replace: true, ...options })
},

Thanks,

Inertia emitted events

More of a question, than an issue per se...

A couple of previous apps I've worked on have used turbolinks and vue - pretty much as @reinink described in his article about backend apps with client rendering

What's useful about using turbolinks in this approach, is that it emits a heap of events, that your application can hook in to - for example - fire off analytics tracking, etc.

I think there might be merit for inertia.js to emit some of its own events for other parts of applications to latch on to.

For example, you could listen for events like click, visit, hardvisit, restore, under an inertia namespace:

document.addEventListener('inertia:visit', (event) => {
    // do something, for example: 
    dataLayer.push({
      'url': event.data.path, // e.g. `/user/1/update`
      'event': event.data.trigger // e.g `updateProfile`
    });
});

If this is something that folks would find useful, I might be able to hack on a PR to add such a feature.

Any thoughts?

Opt out of cached back behaviour in some cases

In the browser, when the previous page has a Cache-Control: no-cache header, the back button will trigger a full page refresh instead of using the cache. I'm looking for a similar solution in Inertia.

I need this for pages that contain forms with CSRF tokens; these break after a back navigation because the token isn't always valid anymore.

[inertia-vue] Vue router Parameter

Hi @reinink ,
I want to pass one parameter to all my vue component that can be selected by user and remember through the appllication even page refresh my parameter not forgottable, can this is possible in inertia-vue.

Thanks

Question: How to browser back correctly

Hi everyone,

we currently have a Laravel application coupled with inertia. I was browsing the issues here and I'm not sure how to handle browser back correctly.

Scenario:

  • visit a detail view in the application (page A)

  • inertia-link to another page B where a form is filled in

  • submit the form with this.$inertia.post

  • in the controller do stuff, create a flash message and redirect()->route to page A again

  • the flash message appears, everything is ok

  • go to another page C to watch some information

  • browser back to page A

  • now, we see the flash message again

Why is that so? Probably because the browser back loads the cached data when page A was initially loaded which includes the flash message.

But what to do, so that the flash message is not appearing again?

Another scenario:

  • a multi-step form process

  • visit form A, fill in the data

  • go from form A to B with a forward button

  • the data is posted to the backend, saved and we redirect to form B

  • we are in form B now

  • go back to form A with the back button

  • the form on A is empty, like our initial visit to the page

  • go back to form A with a back button (inertia-link)

  • the form is filled in, as done by the user

What would be the best way to show a fresh state of form A when the user presses browser back?

I'm not really sure what is expected behaviour here. When pressing browser back, do we want to see the page as it was initially loaded, or in the state the user left it in?

Would be nice if anyone could notch me in the right direction. Thank you in advance ๐Ÿ™๐Ÿป

history.back() Scroll position

I wonder if history.back() can remember scroll position? Also window.scrollY always returns 0 and window.addEventListener can't be installed to a component.. probably all listeners don't work. I'm using Vue.
All I want is to remember scroll position at history.back() and sometimes to refetch/update page.

EDIT:
Also what about infinite scroll? I bet it will be re-rendered at history.back(). Maybe it will work if we will use preserve-state and remember: 'page', but still no scroll remember ;) - not sure tho.

django user authentication and authorization

Hi Everyone,
I need suggestion on the following issue, actually I start developing a small erp in django. Iโ€™m quite confuse about how to handle user authentication and authorization. My project architecture is

๏ƒ˜ ERP (Main Project)
o HR (App)
o Finance (App)
o Payroll (App)
o Sale (App)
How to implement login system in above architecture?

Thanks

Inline nprogress css

While Inertia uses nprogress by default for showing page load progress, it doesn't actually include any CSS for it. You are still required to include this on your own (example).

It would be nice to simply inline this somehow. It would be wise to review how Turbolinks does this, since their CSS is mega simple.

Scroll not resetting on the body element

Description

setScroll is not resetting the scroll position on the body.

Steps to reproduce:

  1. Create two pages in an inertia project where you can scroll
  2. Add an Inertia Link to go from page 2 to page 1
  3. Go to page 2 and scroll
  4. Go back to Page 1 using the Inertia Link
setScroll(preserveScroll) {
    if (!preserveScroll) {
      document.querySelectorAll('body,[scroll-region]')
        .forEach(region => region.scrollTo(0, 0))
    }
  },

Info

Go to an Inertia Page where you can scroll, in your console and try to reset the body scroll position manually using document.querySelector('body').scrollTo(0, 0)

In both cases it's not resetting the scroll position, you can however try to select the html element instead of the body element and it should work

Flash messaging in an Inertia app

In the process of playing around with Inertia, I ran into the question of how best to handle flash messaging. In a traditional server-side rendered app, I would usually just flash the data I want directly to the session from the controller and then on page reload, that data would be available and would trigger the message to appear. Given that Inertia apps don't have that page reload though, I found myself scratching my head this weekend trying to get flash messages working.

One of the things I tried after that was creating a plugin that would manage my alerts for me. The idea was in my submit's then callback, before I replace the URL, I would flash any message to my plugin and then move over to the new page.

then (() => {
    this.$alert.success('User was successfully created.');

    Inertia.replace(route('users.index'));
})

Unfortunately, this doesn't work because the alert manager is inside of my layout file, so that whole thing gets replaced with the new component when Inertia.replace is called.

I wanted to see what people thought would be a good way to tackle the flash messaging issue in Inertia apps. Due to how fast the whole thing is, it can be a little jarring to move back to an index page and not have any confirmation that something was successfully added, especially on a page where there may be a lot of data.

Would love to get a conversation rolling with a few folks on this one!

AngularJS adapter

Hi everyone,

Is there any possibility for Inertia to provide an AngularJS(1.x) adapter?

Unfortunetly at the moment I don't have knowledge enough to make such adapter, but would use it for sure.

Maybe Jonathan could make a little poll so we can see if other developers also have interest.

Yarn blows up something?

Hey, I'm leaving this partially as a marker for other people but if you run yarn instead of npm you could have some issues. Specifically yarn builds do something...different...so a page component seems not to get loaded. I'd get a cannot find ./undefined as an error in my console. I'd clear caches, recompile everything, make sure paths are correct and still nothing. I deleted my node_modules folder and still didn't get it to work. Then I deleted my node_modules and tried npm install and npm run dev and with no other change my pages were found. Normally I'd try to dig into this more to figure out what's going on I just don't have the time right now but maybe I'm doing something wrong with yarn or maybe this is a known issue. Happy to provide any other info if needed.

Google search console

Hi
Just testing our interia (react version) for a website, and it seems that google search console does not like the intertia.js file in the main intertia repo.
It throws an error when trying to parse inertia

The error
image

First line of stack trace
image

The part it is complaining about.
image

Sadly I havent been able to fix a way to fix it myself (I have added @babel/polyfill but it still throws the error.

Cannot read property 'component' of undefined

Getting an error when loading the page in Chrome. Building succeeds though:

TypeError: Cannot read property 'component' of undefined
  at setPage(./node_modules/inertia/src/inertia.js:123:1)
  at init(./node_modules/inertia/src/inertia.js:20:1)
  at call(./node_modules/inertia-vue/src/app.js:25:12)
  at invokeWithErrorHandling(./node_modules/vue/dist/vue.runtime.esm.js:1854:1)
  at callHook(./node_modules/vue/dist/vue.runtime.esm.js:4213:1)
  at _init(./node_modules/vue/dist/vue.runtime.esm.js:5002:1)
  at new b(./node_modules/vue/dist/vue.runtime.esm.js:5148:1)
  at createComponentInstanceForVnode(./node_modules/vue/dist/vue.runtime.esm.js:3283:1)
  at i(./node_modules/vue/dist/vue.runtime.esm.js:3114:1)
  at createComponent(./node_modules/vue/dist/vue.runtime.esm.js:5972:1)
  at createElm(./node_modules/vue/dist/vue.runtime.esm.js:5919:1)
  at __patch__(./node_modules/vue/dist/vue.runtime.esm.js:6510:1)
  at _update(./node_modules/vue/dist/vue.runtime.esm.js:3939:1)
  at call(./node_modules/vue/dist/vue.runtime.esm.js:4060:1)
  at get(./node_modules/vue/dist/vue.runtime.esm.js:4473:1)
  at new dn(./node_modules/vue/dist/vue.runtime.esm.js:4462:1)
  at vm(./node_modules/vue/dist/vue.runtime.esm.js:4067:1)
  at $mount(./node_modules/vue/dist/vue.runtime.esm.js:8409:1)
  at call(./resources/js/app.js:99:4)
  at __webpack_require__(webpack/bootstrap:63:1)
  at call(./node_modules/moment/locale/x-pseudo.js:5:59)
  at __webpack_require__(webpack/bootstrap:63:1)
  at ? (webpack/bootstrap:195:1)
  at ? (webpack/bootstrap:195:1)

I also took a screenshot of what I am seeing in Sentry:

2019-05-16-16-28-sentry io

Return page object after Inertia.visit

In PingCRM there's a part where the $page property is checked to determine what to do next after a visit.

https://github.com/inertiajs/pingcrm/blob/4b8849ac43aa0519e770068ce7a6d88774a2bba0/resources/js/Pages/Users/Edit.vue#L83-L90

This works in Vue, but is not possible in React because of the way state in React works. (at least not in a straightforward way)

How about we return the new $page object in the promise instead, so it works everywhere?

The PingCRM code would become:

this.$inertia.post(this.route('users.update', this.user.id), data)
  .then(page => {
    this.sending = false
    if (Object.keys(page.errors).length === 0) {
      this.form.photo = null
      this.form.password = null
    }
})

Property or method "$page" is not defined

I share some data using Inertia::share() from my laravel service provider, I can see it properly from vue devtools. Any ideas?

edit: $parent.$parent.page works just fine
edit2: The old way with inject: ['page'] seems to work as well. No idea why I cant use $page, compared my code to the pingcrm demo app where it works and cant find anything.

Layout.vue

<template>
    <div>
        <div class="bg-white border-b">
            <div class="container flex justify-between mx-auto max-w-4xl">
                {{ $page }}
            </div>
        </div>

        <div class="container max-w-4xl mx-auto px-5 pt-12">
            <slot />
        </div>
    </div>
</template>

app.js

import Inertia from 'inertia-vue';
import Vue from 'vue';

Vue.use(Inertia);

let app = document.getElementById('app')

new Vue({
  render: h => h(Inertia, {
    props: {
      initialPage: JSON.parse(app.dataset.page),
      resolveComponent: name => import(`@/pages/${name}`).then(module => module.default),
    },
  }),
}).$mount(app);

package.json

{
    "private": true,
    "scripts": {
        "dev": "npm run development",
        "development": "cross-env NODE_ENV=development node_modules/webpack/bin/webpack.js --progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js",
        "watch": "npm run development -- --watch",
        "watch-poll": "npm run watch -- --watch-poll",
        "hot": "cross-env NODE_ENV=development node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot --config=node_modules/laravel-mix/setup/webpack.config.js",
        "prod": "npm run production",
        "production": "cross-env NODE_ENV=production node_modules/webpack/bin/webpack.js --no-progress --hide-modules --config=node_modules/laravel-mix/setup/webpack.config.js"
    },
    "devDependencies": {
        "@babel/plugin-syntax-dynamic-import": "^7.2.0",
        "axios": "^0.18",
        "cross-env": "^5.1",
        "form-backend-validation": "^2.3.6",
        "inertia-vue": "inertiajs/inertia-vue",
        "laravel-mix": "^4.0.7",
        "lodash": "^4.17.5",
        "popper.js": "^1.12",
        "resolve-url-loader": "^2.3.1",
        "sass": "^1.15.2",
        "sass-loader": "^7.1.0",
        "tailwindcss": "^1.0.1",
        "vue": "^2.5.17",
        "vue-template-compiler": "^2.6.10"
    }
}

Improve history navigation on iOS

Right now going forward/back in history on iOS is a mess. I'm not honestly sure if there is anything that can be done to fix this. Probably would mean reintroducing caching to Inertia.

2019-04-08 12 15 35

Documentation

Start using inertia with Laravel and i really love it. Great work @reinink! ๐Ÿ‘๐ŸŽ‰
PingCRM is a really good starting point to learn some basic stuff.

To learn more what inertia can do, is there any documentation?

Allow custom loading indicators

Currently Inertia uses nprogress for its loading indicator. However, it would be nice to support other libraries. We'd simply have to expose this as a configuration option somehow.

For example:

new Vue({
  render: h => h(Inertia, {
    props: {
      component: app.dataset.component,
      props: JSON.parse(app.dataset.props),      
      resolveComponent: (component) => { ... },
      beforeVisit: () => { /* start loading indicator */ },
      afterVisit: () => { /* stop loading indicator */ },
    },
  }),
}).$mount(app)

Support file uploads

We're trying to do file uploads with Inertia. That means the Content-Type header needs to be set. Currently using this beautiful snippet ๐Ÿ˜ฌ

axios.interceptors.request.use(config => {
    if (config.data instanceof FormData) {
        config.headers['Content-Type'] = 'multipart/form-data';
    }

    return config;
});

Is there any better way to modify headers for specific visits?

Move Inertia config out of adapters

As we add more features to Inertia itself, we constantly need to update the adapters, as they serve as the entry point to Inertia. However, for most features, the adapter is simply a proxy. I'm starting to think it might be better to push more of this work to Inertia directly, and let the adapters remain a little simpler.

For example, currently we do this:

import Vue from 'vue'
import { InertiaApp } from '@inertiajs/inertia-vue'

let app = document.getElementById('app')

Vue.use(InertiaApp)

new Vue({
  render: h => h(InertiaApp, {
    props: {
      initialPage: JSON.parse(app.dataset.page),
      resolveComponent: name => import(`@/Pages/${name}`).then(module => module.default),
      transformProps: props => { ... },
    },
  }),
}).$mount(app)

What I'm proposing:

import Vue from 'vue'
import { Inertia } from '@inertiajs/inertia'
import { InertiaApp } from '@inertiajs/inertia-vue'

Inertia.init({
  initialPage: JSON.parse(app.dataset.page),
  resolveComponent: name => import(`@/Pages/${name}`).then(module => module.default),
  transformProps: props => { ... },
})

let app = document.getElementById('app')

Vue.use(InertiaApp)
new Vue({ render: h => h(InertiaApp) }).$mount(app)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.