Visit inertiajs.com to learn more.
inertiajs / inertia-laravel Goto Github PK
View Code? Open in Web Editor NEWThe Laravel adapter for Inertia.js.
Home Page: https://inertiajs.com
License: MIT License
The Laravel adapter for Inertia.js.
Home Page: https://inertiajs.com
License: MIT License
Visit inertiajs.com to learn more.
We should make InertialViewFactory
implements \Illuminate\Contracts\View\Factory
instead of default ViewFactory
of Laravel. With InertialViewFactory
view()
function ( return view('viewName', [ /* data */])
)
If I'm not mistaken, Inertia::share() adds share data to each response. However, in most of the case we only need to fetch the shared data once, for example, auth user usually won't change.
I was wondering if we can add an shareOnce
method to avoid repeatedly sending share data. This implies that server need to store a state telling if the data is shared already. To avoid using session/cookie, we might need to pass some meta data in request/response. Here is a raw idea in the context of vue
this.$page
)It adds complexity, but it can reduce lots of unnecessary payloads. I'd love to do some experiment and create a PR if this feature request is accepted. pls let me know your thoughts.
My app contains two views - a frontend and a backend with different layouts. The resources/js
folder also has 2 different Vue instances - one for frontend and one for backend. I have the frontend rendering Inertia components and pages just fine, but when I try to implement the same in the backend, I get a blank page with empty HTML tags. This is my setup:
/* in AppServiceProvider */
public function register()
{
// dynamically set the rootview based on whether the route is backend or frontend
// can also be done in a middleware that wraps all admin routes
if(request()->is('admin/*')){
Inertia::setRootView('admin.app');
} else {
Inertia::setRootView('frontend.app');
}
....
}
In my resources/views
I have a frontend/app.blade.php
file with the @inertia
helper, which works great and renders the Vue components as expected. But the same setup in admin/app.blade.php
returns a blank page, does not even render the metatags or the style and script tags on the page talk less of content. But the setRootView
seems to work because when I pass in a view name that does not exist, I get an error. So I suppose it is reading the appropriate view file but not rendering anything.
Not sure what I am doing wrong.
There's a lot of confusion around error handling at the moment. When a server error happens, Laravel returns a non-Inertia response, which means Inertia renders the response in a modal.
People often ask for a way to disable the modal behaviour. This is not the idiomatic solution to the problem; the correct solution is to ensure your server always returns an Inertia response.
In Laravel, this can be achieved by modifying the exception handler.
A basic example:
public function render($request, Exception $exception)
{
if ($exception instanceof ModelNotFoundException) {
return Inertia::render('Errors/NotFound');
}
return parent::render($request, $exception);
}
This is a tedious job; you need to ensure you've caught all default Laravel cases, and it's a lot of boilerplate code to add to every project.
Laravel's default bahaviour is to render a Blade view based on the error's response code, like errors.404
, errors.500
etc. The inertia-laravel package could mimic this method.
public function render($request, Exception $exception)
{
return Inertia::renderException($request, $exception);
}
We could also ship a "check" for applications with multiple parts, including non-Inertia parts like an API or separate homepage.
public function render($request, Exception $exception)
{
if (Inertia::isInertiaRequest($request)) {
return Inertia::renderException($request, $exception);
}
return parent::render($request, $exception);
}
This would return an response with a standardized component name, for example Inertia::render('Errors/NotFound')
. Note that JavaScript functions aren't allowed to start with a number, so we'd need to either use explicit names (NotFound
), or a prefix (Error404
).
What needs to be done?
Inertia::render
Hey, when using a custom port for local development this seems to be a problem. I'm running my app at localhost:3000
. I created two routes /test
and /test2
but whenever I go to another route with <inertia-link />
I will get this error in my console:
Uncaught (in promise) DOMException: Failed to execute 'pushState' on 'History': A history state object with URL 'http://localhost/test2' cannot be created in a document with origin 'http://localhost:3000' and URL 'http://localhost:3000/test'.
at Object.setState (webpack-internal:///./node_modules/inertia/src/inertia.js:124:59)
at eval (webpack-internal:///./node_modules/inertia/src/inertia.js:93:14)
It seems that my port is lost here: https://github.com/inertiajs/inertia-laravel/blob/master/src/Component.php#L59. Changing Request::fullUrl()
to Request::path()
does the trick for me but I'm not sure if this will cause any other problems.
I have set it up and run this to test.
I am getting following error
Undefined variable: page (View: /var/www/resources/views/layouts/app.blade.php) (View: /var/www/resources/views/layouts/app.blade.php)
Below is my main view
`
and Controller
`<?php
namespace App\Http\Controllers;
use Inertia\Inertia;
class WelcomeController
{
public function show()
{
return Inertia::render('Event')->with('event', "Good");
}
}
`
Please help
Instead of calling Inertia::share() many times for each piece of data:
Inertia::share('app.name', Config::get('app.name'));
Inertia::share('flash', function () {...});
Inertia::share('errors', function () {...});
Inertia::share('auth.user', function () {...});
It would be nice to define this in a single callback:
Inertia::share(function () {
return [
'flash' => [
'success' => Session::get('success'),
],
'errors' => Session::get('errors') ? Session::get('errors')->getBag('default')->getMessages() : (object) [],
'auth' => [
'user' => Auth::user() ? [
'id' => Auth::user()->id,
'first_name' => Auth::user()->first_name,
'last_name' => Auth::user()->last_name,
'email' => Auth::user()->email,
] : null
],
];
});
I have \URL::forceScheme('https');
in app boot. However I noticed that requests still go to http://...
and this doesn't seem to complete visually. If I refresh the page I can see that the POST
or DELETE
was successful but nprogress never completes and it and the page goes into a crawl state.
I was wandering, what would be the recommended way of handling errors when using Inertia with Laravel?
Here's my current solution:
In order to have consistent error pages when making requests directly and when making them through Inertia, in an app I'm using for testing Inertia, I've decided to show error pages only using Inertia. So, I have a trait that I apply to App\Exceptions\Handler
class:
<?php
namespace App\Exceptions;
use Inertia\Inertia;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;
trait ShowsErrorPageUsingInertia
{
/**
* Render the given HttpException.
*
* @param \Symfony\Component\HttpKernel\Exception\HttpExceptionInterface $e
* @return \Symfony\Component\HttpFoundation\Response
*/
protected function renderHttpException(HttpExceptionInterface $e)
{
$statusCode = $e->getStatusCode();
$inertiaResponse = Inertia::render('Error', [
'code' => $statusCode,
'message' => $this->responseStatusText($statusCode),
]);
if (! $inertiaResponse instanceof Response) {
return new Response($inertiaResponse, $statusCode);
}
return $inertiaResponse;
}
/**
* Get the status text based on status code.
*
* @param int $statusCode
* @return string
*/
private function responseStatusText($statusCode)
{
if ($statusCode === 419) {
return 'Page Expired';
}
return Response::$statusTexts[$statusCode] ?? 'Unknown Error';
}
}
I could have inlined it in the class, but having this in a trait feels better to me ๐
And I have Error.vue
page that shows error and short message, in the same way that Laravel does usually.
So far it's worked perfectly for me ๐
Is it possible to do a redirect without going through Inertia?
For example, if I do a post request using ( $inertia.post
) to ( /posts
) and I have something like this in the store method:
// code ...
return redirect()->route('/admin/posts)
I want to do a full page refresh without going through Inertia.. is this possible?
Hi there nice work ๐
I'm developing my admin app using inertia and I got some Resource classes on my front-end so all my controllers pass a resource
parameter to pages like this:
Inertia::render('Resource/Index',[
'resource' => 'BlogPost',
// ...
])
so it's good unless i have more than one methods on my resource controller ( mostly all CRUD methods ). so i prefer share
resource parameter in __constructor
method instead of repeating it at every method like :
Class BlogPostController extends Controller{
__constructor(){
Inertia::share('resource','BlogPost');
}
//...
}
So i though it's cleaner to make Inertia macroable so it would be possible do something like:
Class BlogPostController extends Controller{
__constructor(){
Inertia::resource('BlogPost');
}
//...
}
I feel like anybody who will end up using Inertia will always have to refer to the documentation to get the root <div>
and it's data-component
details.
Have you thought about whether an @inertia
blade action would be worthwhile?
In my opinion, Inertia will make a huge step for Laravel community, really thank you for this awesome work. I'll be very happy to help you out writing the docs using my package larecipe if you want of course. Thank you again ๐โค๏ธ
It would be nice to use Laravel's default dot notation when passing views in subfolders to the render()
method.
// currently
return Inertia::render('User/Create');
// proposal: like we are used to in laravel
return Inertia::render('user.create')
Is support for Eloquent's API Resources planned? We have models that a) have properties only available after a certain date and b) other properties only available to admin users.
With an API resource, we can just do stuff like:
$return = [
'id' => $this->id,
'name' => $this->id,
];
if(auth()->user()->isAdmin) {
$return['answer'] = 'foo';
}
return $return;
Being able to do this would be spectacular:
return Inertia::render('Model')
->with('model', new ModelResource($model);
and this:
return Inertia::render('List')
->with('models', new ModelResource::collection(Model::all());
Route::get('/contact', function () {
Khead::setTitle('acontact');
$event = "ok this is event";
return Inertia::render('Contact', ['eventi' => $event])
->with(['meta_description' => $event]);
});
<inertia-link href="/contact">contact</inertia-link>
when I click contact route that time return an error
BadMethodCallException
Method Illuminate\Http\JsonResponse::with does not exist.
but normal anchor tag works properly.
It would be nice if withViewData()
method could accept array. That way one, can pass multiple value.
This throws an error (Too few arguments to function)
public function index() {
return Inertia::render('Contact/Index')->withViewData([
'title' => 'Contact Us | My App',
'description' => 'Contact us with your comments, questions, and suggestions',
'meta' => 'Some other SEO meta'
]);
}
Then access the variables in blade as
<title>{{ $title }}</title>
<meta name="description" content="{{ $description }}.">
<meta name="description" content="{{ $meta }}">
Or am I missing something
why there is no any detail about setup and installation
If I pass the name of a helper function to the second parmeter of Intertia::render, it will be executed.
return Inertia::render('Index', [
'user' => $user,
'columns' => [
'username',
'retry',
],
]);
This will result in retry() being called.
Too few arguments to function retry(), 1 passed and at least 2 expected
In current project I need to use layout.blade.php which doesn't have Inertia.js tag i.e.
integrated.But after integrating Intertia.js now I've an error which is $page variable undefined.
So, is there any way we can use multiple layout file based on condition?
Thanks,
Rutvij
For now, when adding a shared data, you must set a key for the shared data.
Inertia::share('auth.user', function () {
if ($NotNull) {
return [
'key' => 'value',
];
}
});
If this key didn't pass the if statement, the key will have a null
as a value.
Is there a way to add a shared key in this way:
Inertia::share(function () {
$sharedData = [];
if ($NotNull) {
$sharedData['some-key'] = [
'key' => 'value',
];
}
if ($NotNull) {
$sharedData['some-key-2'] = [
'key' => 'value',
];
}
return $sharedData;
});
This way the key will be shared only if it has some value. I don't want to have many shared keys with "null" values.
Pagination data in API resources appears to be handled by the toResponse
function of Illuminate\Http\Resources\Json\PaginatedResourceResponse
.
That means this:
return Inertia::render('Foo', [
'foo' => FooResource::collection(Foo::paginate()),
]);
gets the correctly transformed collection, but it's missing the links
(and other) metadata.
I'm able to work around it by doing this:
return Inertia::render('Foo', [
'foo' => new FooCollection(Foo::paginate()),
]);
and having FooCollection do this:
return [
'data' => FooResource::collection($this->collection),
'links' => $this->links()
];
but it's not as elegant as the default behavior in Laravel.
We need a way to retrieve Inertia's page's data in blade. By adding a method like:
Inertia::get('')
For the readers:
There is a lot of use cases for this, one of them would be when sharing a page in social networks.
For example, when sharing a page to Facebook, Facebook will go to your page and look for "open graph" metadata. In which Facebook's bots will not see ( since Facebook 's bots doesn't render JS ). Therefore, "open graph" metadata must be rendered server side for the first page load.
This is a known issue been around for SPA frameworks. And since Inertia is ( server-driven single page apps ), It solve this issue easily without any complicated workarounds.
--
For the ones who interested in SEO:
This also can be helpful to set the page's ( title - meta description - etc) in Blade ( for the first page load ). And then when a user do Inertia.visit, we can change the page's title like this:
let title = document.title;
if (title === this.page.props.meta.title) return;
title = this.page.props.meta.title;
Installing pingcrm and viewing the source for any of the pages (contacts, organizations, etc does not show any meta tag content for SEO in the <head>
element.
I also found this PR here:
#8
but it's unclear to me how to do this.
I want to be able to support the following SEO tags if the source is viewed, so that the search engine crawler sees the tags when it indexes the page.
If this is indeed supported, possible to update https://github.com/inertiajs/pingcrm with an example? These are the SEO tags I am considering (comprehensive list, but picking just one, like should suffice for demo purposes)
<title></title>
<link rel="canonical" href="" />
<meta name="robots" content="index, follow" />
<meta charset="utf-8">
<meta name="description" content="">
<meta name="keywords" content="">
<meta name="last-updated" content="2019-07-24 00:43:07 UTC">
<meta name="environment" content="production">
<meta name="user-signed-in" content="">
<meta property="og:type" content="" />
<meta property="og:url" content="" />
<meta property="og:title" content="" />
<meta property="og:description" content="" />
<meta property="og:site_name" content="" />
<meta name="twitter:site" content="">
<meta name="twitter:creator" content="">
<meta name="twitter:title" content="">
<meta name="twitter:description" content="">
<meta name="twitter:card" content="">
<meta name="twitter:widgets:new-embed-design" content="on">
<meta property="og:image" content="" />
<meta name="twitter:image:src" content="">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<meta name="apple-mobile-web-app-title" content="">
<meta name="application-name" content="">
<meta property="fb:pages" content="" />
<meta name="theme-color" content="#000000" />
Since the upgrade to 0.2 a resource collection has a data property that contains the collection of resources. I get that. That is awesome.
What I don't understand, and I hope this is a bug, is why this also applies to a single resource.
For example:
return Inertia::render('Home', [
'projects' => ProjectResource::collection($projects),
Gives me a Vue object like this:
Again, makes complete sense to me! You just create a loop over project.data
in Vue and can simply use {{ project.name }}
to render data for a single project.
But, this example:
return Inertia::render('Project/Show', [
'project' => new ProjectResource($project),
Gives me a Vue object like this:
And here I would have expected the old behavior. A project object with the properties directly inside it and not nested within a data property. Because now I would have to rewrite everything from
{{ project.name }}
to {{ project.data.name }}
.
So for a single project inside a project collection I can use {{ project.name }}
but for the single resource I need to use {{ project.data.name }}
. That is just not consistent.
So again, I would just like to make sure that this is the intended behavior for a single resource. It just looks to much like a bug to me.
When using shared data in Vue.js passed from my AppServiceProvider it returns this message error when i try to load the page.
app.js:64 Uncaught (in promise) TypeError: Cannot read property 'call' of undefined
at __webpack_require__ (app.js:64)
at Object../node_modules/css-loader/index.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/Shared/Admin/Toolbar.vue?vue&type=style&index=0&lang=scss& (0.js?id=ad5928fae408418d3200:295)
at __webpack_require__ (app.js:64)
at Object../node_modules/style-loader/index.js!./node_modules/css-loader/index.js!./node_modules/vue-loader/lib/loaders/stylePostLoader.js!./node_modules/postcss-loader/src/index.js?!./node_modules/sass-loader/dist/cjs.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/Shared/Admin/Toolbar.vue?vue&type=style&index=0&lang=scss& (0.js?id=ad5928fae408418d3200:334)
at __webpack_require__ (app.js:64)
at Module../resources/js/Shared/Admin/Toolbar.vue?vue&type=style&index=0&lang=scss& (0.js?id=ad5928fae408418d3200:1504)
at __webpack_require__ (app.js:64)
at Module../resources/js/Shared/Admin/Toolbar.vue (0.js?id=ad5928fae408418d3200:1453)
at __webpack_require__ (app.js:64)
at Module../node_modules/babel-loader/lib/index.js?!./node_modules/vue-loader/lib/index.js?!./resources/js/Shared/Layout.vue?vue&type=script&lang=js& (0.js?id=ad5928fae408418d3200:250)
This is how i pass my data on my boot function inside AppServiceProvider:
Inertia::share([
// Lazily
'auth' => function () {
return [
'user' => Auth::user() ? [
'id' => Auth::user()->id,
'first_name' => Auth::user()->name,
'last_name' => Auth::user()->surname,
'profile_image' => Auth::user()->profile_image,
] : null
];
},
'errors' => function () {
return Session::get('errors')
? Session::get('errors')->getBag('default')->getMessages()
: (object) [];
},
]);
My web.php route
Route::get('/')->name('dashboard')->uses('DashboardController')->middleware('auth');
My Vue file:
<p class="font-semibold text-gray-900 leading-none">{{ $page.auth.user.first_name + ' ' + $page.auth.user.last_name }}</p>
I am doing a simple login form, using the existing login logic of LoginController@login
The request hits the controller successfully, but when there is validation failure, the response is always missing props. In this case I am not able to get the validation errors.
response sample:
{component: "front/auth/login", props: [], url: "/login", version: null}
component: "front/auth/login"
props: []
url: "/login"
version: null
this is my vue code
export default {
data() {
return {
form: {
email: null,
password: null,
remember: 1
}
}
},
methods: {
submit() {
this.$inertia.post('/login', this.form).then((response) => {
console.log(this.$inertia.page);
});
}
}
}
and the html login form is very simple:
<form class="flex flex-col w-full bg-white rounded-lg shadow p-8 mt-10" @submit.prevent="submit">
<label class="form-group">
<span class="form-label">Email</span>
<input type="email" name="email" class="form-input" tabindex="1" v-model="form.email" autofocus>
</label>
<label class="form-group">
<span class="form-label">
<span class="form-label">
Password
<a href="#" class="float-right text-xs text-blue-500 hover:text-blue-600 hover:underline">Forgot Password?</a>
</span>
</span>
<input type="password" name="password" class="form-input" tabindex="2" v-model="form.password">
</label>
<button type="submit" class="btn btn-blue btn-block">Login</button>
</form>
Also I am using the latest version of each package:
inertia 0.1.3
inertia-vue 0.1.1
inertia-laravel 0.1.0
What would be the best way to transform original Laravel authentication to Inertia?
I saw PingCRM demo, but I can't get authentication working well like one in PingCRM...
Thanks for helping!
Sometimes we want to redirect the user to a non-Inertia environment after a visit.
Inertia already supports something similar under the hood, for asset versioning.
We added this little helper function in our app, but it feels hacky:
function redirectWithoutInertia(string $url)
{
return response('', SymfonyResponse::HTTP_CONFLICT)->header('x-inertia-location', $url);
}
Would it make sense to add an Inertia::forceRedirect($url)
method to inertia-laravel?
I really like this project, however I'm wondering if what I'm trying to accomplish is currently possible. I would really like to develop with HMR (npm run hot), as you can change the content of vue files and they're being updated in the browser while maintaining the state of the component.
However, when I try to update css files, the browser becomes blank. Console is showing TypeError: null is not an object (evaluating 'document.body.getElementsByTagName')
With some searches on Google I came across a couple of posts stating that Laravel Mix and HMR mode only works well for .vue files. CSS files are not being watched/updated. So I wanted to switch to Browsersync to get CSS file changes being detected and auto reloading the browser. That won't work either because the inertialinks trigger an error because the domain 0.0.0.0:3000 is not the same as the project url. The console shows Unhandled Promise Rejection: SecurityError: Blocked attempt to use history.pushState() to change session history URL from https://localhost:3000/about to https://<project>.test/.
.
I understand the project is very early stage, but I was wandering if its possible to get HMR working in combination with Browsersync. My goal is to get HMR working with support for CSS file changes, that would make development a real bliss. If you guys have an alternative development flow I'd be happy to learn about it.
Thanks
Is there the ability to do sth similar to laravel's blade template '@Push',
using inertia-vue with laravel, say i have base template, but based on different componenets, i wish to make sth similar to @push('custom1'), @push('custom2')
?
I know that the opposite has already been discussed (and I struggled with that too) - namely getting non-inertia responses not to load into a modal. However, I wonder if it would be possible to have an Inertia Response load into a modal? Is there any way of triggering this (other than re-implementing Response and reneder to fiddle with the x-inertia
on my side?
Thank you.
It would be nice to be able to get to the first byte somehow without having to load all needed data. I know it would be alot to ask, but if it was possible to split up the returned data somehow, to make the page render fast, and then populate the rest afterwards.
I am not a 100% sure how it could be done, but perhaps using something like
Inertia::render('Page')->withDelayedData($data);
It would then load the page without data, and then perform an ajax request to the same route to get the actual data.
This would in turn add the nprocess loader to the page at once, ensuring a better user experience.
When I use route groups in my web.php
file it sometimes breaks my app.
For example I tried to do this and my entire app showed a blank screen (although the login screens seem to work)
Route::group(['suffix' => 'profile'], function() {
Route::get('/', 'ProfileController@index')->name('profile.index');
});
However, when I take my routes out of groups, like this everything works perfectly fine.
Route::get('/profile', 'ProfileController@index')->name('profile.index');
This is what my ProfileController.php
file looks like:
<?php
namespace App\Http\Controllers;
use App\User;
use Inertia\Inertia;
use Illuminate\Http\Request;
class ProfileController extends Controller
{
public function __construct()
{
$this->middleware('auth');
}
public function index()
{
return Inertia::render('Profile/Index');
}
}
So I have a strange edge case with the latest render function (included for posterity).
From ResponseFactory.php
public function render($component, $props = [])
{
$props = array_merge($this->sharedProps, $props);
foreach ($this->sharedPropsCallbacks as $callback) {
$props = array_merge($props, App::call($callback));
}
array_walk_recursive($props, function (&$prop) {
if (is_callable($prop)) {
$prop = App::call($prop);
}
});
return new Response($component, $props, $this->rootView, $this->getVersion());
}
I have an array of color options I'm passing through to the view. One of these colors is tan (saved as Tan
). When it gets to checking the callable props, it assumes I mean tan()
and gives me an error on the proper usage of the tan function. Anyway to escape out things like that? Works fine in the previous iteration.
I think this is happening because the Inertia\ResponseFactory
class is being instantiated twice during the course of the test, but the rootView property is only reset the first time. We could sort this out by injecting the root view as a nullable constructor parameter and then binding the value of the $rootView
primitive requested by the Responsable class in the setRootView()
method.
If this solution makes sense I can put together a PR.
withViewData() method accept key and value but in documentation it is mention that key and value pair will be an array but correct implementation is like this
//In controller
$meta['description'] = 'You description';
$meta['keywords'] = 'Your keyword';
return Inertia::render('Event', ['event' => $event])->withViewData('meta', $meta);
//in root template
<meta name="description" content="{{ $meta['description'] }}">
<meta name="keywords" content="{{ $meta['keywords'] }}">
I'm trying to test a route that should pass the auth user as a shared prop data, along with others(app.name...etc). I am only seeing the prop data defined in the controller.
Anyone run into this issue? Any suggestions... @reinink
btw, all shared prop data are being passed down to the Vue page component successfully and the json_encoded version can be seen in page view source. I just can't test it.
ErrorException : explode() expects parameter 2 to be string, object given
at C:\wamp64\www\58FP\vendor\laravel\framework\src\Illuminate\Support\Arr.php:516
if (is_null($key)) {
return $array = $value;
}
**$keys = explode('.', $key);**
while (count($keys) > 1) {
$key = array_shift($keys);
Exception trace:
1 explode(".", Object(Closure))
C:\wamp64\www\58FP\vendor\laravel\framework\src\Illuminate\Support\Arr.php:516
2 Illuminate\Support\Arr::set([], Object(Closure))
C:\wamp64\www\58FP\vendor\inertiajs\inertia-laravel\src\ResponseFactory.php:25
One thing which would be helpful in my specific application would be having a feature such as the view composers in Laravel. Currently I'm building a simple solution to do this in my own project, but I'm wondering if there would be any interest of putting this in the core?
I'd be happy to create a pull request for this.
Let me know what you think!
There are a few nice inertia presets out there - like mentioned in #35 or inertiajs-preset. Still it would be really nice to have an official
preset which could also override/extend the default make:auth
command to publish standard views for
and Controllers which handle the Inertia::render()
responses on the GET
requests.
Hi,
I would like to make Laravel Dusk tests for a Laravel/Inertia app. The thing that doesn't seem to work is that the test steps don't seem to have knowledge of page-changes (I think).
When I build in a pause after a button press, the tests seem to work, but this is really very clunky and the pause time depends on the speed of the CPU where the tests are running.
Example:
/**
* @test
*/
public function wrong_password()
{
$user = factory(User::class)->create();
$this->browse(function (Browser $browser) use ($user) {
$browser->visit('/login')
->type('email', $user->email)
->type('password', 'wrong_password')
->press('Login')
->pause(1000)
->assertSee('These credentials do not match our records.');
});
}
Is there a better way to wait for the moment when the assertions can be made.
If I build a Laravel package, I hope I can load Inertia views into the package.
Load Inertia views example:
use Inertia\Inertia;
public function boot()
{
Inertia::loadViewsFrom(__DIR__.'/path/to/views', 'my-package');
}
Usage Inertia views example:
use Inertia\Inertia;
class HomeController extends Controller
{
public function index()
{
return Inertia::render('my-package::Home/Index', [
...
]);
}
}
Can it be achieved?
Updated on 2022/07/03:
Thanks all for the ideas, inspired me to create the Inertia Plugin to resolve this issue.
Hello,
I'm trying to render a Vue Component that it is outside of the Pages folder but it's inside a directory on the same level of the Pages folder.
Is there a way to render it?
Example:
return Inertia::render('Shared/Example');
Instead of :
return Inertia::render('Pages/Example');
There's no production mode. To make it, we can't show error response into a modal. But, I don't really know if Laravel has to handle this case, or if Inertia should.
When an error occurred during navigation (using X-Inertia
header), the modal is shown containing the error content (debug purpose), but never touches the vue component. I don't know how to manage the case. What a production mode need ? Not only the dev console to store the exception, but also a client feedback. I really don't know if this job should be done by Laravel, Inertia or various wrappers (inertia-vue
, etc.).
A Laravel response will simply validate the error URL by loading an error component on it, I don't think it's the best way to manage that because if we want create a modal, we can't. Inertia cannot really do that, because it doesn't interact with the client directly but through the wrapper, but the wrapper cannot do the job because it is never informed about an axios error.
P.S: Sorry if the issue is confused, my head is about this thing ๐
In web.php I have:
Route::inertia('{any}', 'MyPage');
When calling http://foo.test/
this works fine. MyPage will be loaded. If I call http://foo.test/bar
an exception is raised:
ErrorException thrown with message "array_merge(): Expected parameter 2 to be an array, string given"
Stacktrace:
#59 ErrorException in /Users/marvin/Sites/laravel/vendor/inertiajs/inertia-laravel/src/ResponseFactory.php:53
#58 array_merge in /Users/marvin/Sites/laravel/vendor/inertiajs/inertia-laravel/src/ResponseFactory.php:53
#57 Inertia\ResponseFactory:render in /Users/marvin/Sites/laravel/vendor/laravel/framework/src/Illuminate/Support/Facades/Facade.php:237
#56 Illuminate\Support\Facades\Facade:__callStatic in /Users/marvin/Sites/laravel/vendor/inertiajs/inertia-laravel/src/Controller.php:9
#55 Inertia\Controller:__invoke in /Users/marvin/Sites/laravel/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php:48
#54 Illuminate\Routing\ControllerDispatcher:dispatch in /Users/marvin/Sites/laravel/vendor/laravel/framework/src/Illuminate/Routing/Route.php:219
When I dump the arguments of the render function in inertiajs/inertia-laravel/src/ResponseFactory.php
. I get the following:
$component
is bar
and $props
is MyPage
.
It seems like there are Issues with the route bindings in the Inertia Controller when the route contains a route parameter. When I change the Inertia Controller to be like this:
public function __invoke($component, $props, $x)
{
dd($component, $props, $x);
return Inertia::render($component, $props);
}
This will dump $component
is bar
and $props
is MyPage
and $x
is an empty array.
So the any
parameter in the route is mapped to $component
. Which is obviously wrong.
A possible solution for this might be the following:
public function __invoke()
{
return Inertia::render(request('component'), request('props'));
}
Hi i made a preset for laravel
which scaffold all the stuff you had in a very basic app install of inertia
composer require codeitlikemiley/vuetified-laravel-preset
I would love to improved this preset to either choose vuetify/tailwind for front end
for vuetify i can use my layouts from here
https://github.com/codeitlikemiley/vuetified
So basically this will be an upgrade of that repo.
Which has
custom authentication either jwt or laravel passport
custom websocket either by laravel echo server and laravel websockets
custom make:auth (tailwind/vuetify or both)
I would really love to here a feedback from you guys.
Since the main Author of inertia use tailwind. maybe i can stub some of the login/register pages etc. for those that dont use vuetify
Not an issue, more of a question.
I am getting 409 responses when using <inertia-link>
. The page then reloads the intended url and is working fine, due to this behavior.
Any idea what could be causing this? When visiting directly/testing everything is 200. I feel like there's a conflicting header?
Here are the headers according to Telescope:
{
cookie: "remember_web:applicants_59ba36addc2b2f9401580f014c7f58ea4e30989d=eyJpdiI6IlRja01BVGdhNERGMDVsYzNPaXVVUXc9PSIsInZhbHVlIjoidGRiN2tJRUJldWhcLzJTWE1QanpZQlpzd0dYV3V1em4xWEl6WnJuXC9yVUhPV0FtZDhrVFc0MmMxTkJcL1MyYmlMZFhuZStHZE5uR0s0NjFCM2pJV25ZNGxBUXU1NjVhTGJwVE5SV2RNNWpHNmpSeDFuN1Bmam5nMzBId3BGK2wwYkdzZHRuVHVWVW82a3JMYjlmeG9hdXcxXC9XS3BpdHJPZFZ0YWIrbHZkTkxuOD0iLCJtYWMiOiIxM2JmYWJkYjJlNGM2OTM0YmNiNWZlODFlNTI3MmQ0Yjg5MDEzMTljZmNlMDdlZmE4MmMwMDI2MzQ1NTc3MzMzIn0%3D; XSRF-TOKEN=eyJpdiI6InRUYzMyZjFWeFJtUmFpVTZqdHR1emc9PSIsInZhbHVlIjoickN2a0Jyem5uQ242VW1MWjA4SnFLTFlnSFJSOXF4UWFlXC85eEo4WTB3aGQwNUpSbytoRkl1eVFrOTRPWXZ0dTciLCJtYWMiOiI1ODQ3MzM4ZjZlNDU1NjUxYzY5NWQ3YTkzNjRiMTYyZDZjYTQzMzM4NWU0ZDM0N2JhNmRlYjRmYWUwMWFlY2E5In0%3D; ldi_apply_session=eyJpdiI6Ims3WG5GR2dvOUdiMWlyRGhPZ2h5M0E9PSIsInZhbHVlIjoiejJkd0tOSHFWRFwvUFVqcEpyV2syaVwvSlpYMndrRitQaHJGdWRGTnphOFwvY3BVZjQ3dmlYXC9XZjdXclRtaEhZNjciLCJtYWMiOiIwNzAwNDE5YzhlMmIzOTIyNGYxYWE1MTAyZDVmOWFjZTNlOGZkOTUyNzAwZTM3MjdhNDJjMjlkNjMxMWUyNTExIn0%3D",
accept-language: "en-US,en;q=0.9,ar;q=0.8,fr;q=0.7",
accept-encoding: "gzip, deflate",
referer: "http://ldi-apply.test/steps/1/forms/3/edit",
x-requested-with: "XMLHttpRequest",
x-inertia-version: "a86ad0584af7daf29b57549e69872177",
accept: "text/html, application/xhtml+xml",
content-type: "application/json;charset=utf-8",
user-agent: "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.90 Safari/537.36",
x-inertia: "true",
x-xsrf-token: "eyJpdiI6InRUYzMyZjFWeFJtUmFpVTZqdHR1emc9PSIsInZhbHVlIjoickN2a0Jyem5uQ242VW1MWjA4SnFLTFlnSFJSOXF4UWFlXC85eEo4WTB3aGQwNUpSbytoRkl1eVFrOTRPWXZ0dTciLCJtYWMiOiI1ODQ3MzM4ZjZlNDU1NjUxYzY5NWQ3YTkzNjRiMTYyZDZjYTQzMzM4NWU0ZDM0N2JhNmRlYjRmYWUwMWFlY2E5In0=",
cache-control: "no-cache",
pragma: "no-cache",
connection: "keep-alive",
host: "ldi-apply.test",
content-length: ""
}
The response in Telescope just says "HTML Response"
.
How can I use Storage::download()
with Inertia? Currently it just opens up a modal with the contents of the downloaded file..
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.