Skip to content

Commit c1639e9

Browse files
authored
Merge pull request #749 from inertiajs/ensure-component-exists
[2.x] Support for checking if the component exists when rendering
2 parents 421b33d + 88d55d7 commit c1639e9

File tree

5 files changed

+87
-19
lines changed

5 files changed

+87
-19
lines changed

config/inertia.php

Lines changed: 34 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,36 @@
3131

3232
],
3333

34+
/*
35+
|--------------------------------------------------------------------------
36+
| Pages
37+
|--------------------------------------------------------------------------
38+
|
39+
| If you want to ensure that the pages exist, you can set `ensure_pages_exist` to true.
40+
| This will throw an exception if the component does not exist on the filesystem
41+
| when rendering a page. You may configure this separately for testing.
42+
|
43+
*/
44+
45+
'ensure_pages_exist' => false,
46+
47+
'page_paths' => [
48+
49+
resource_path('js/Pages'),
50+
51+
],
52+
53+
'page_extensions' => [
54+
55+
'js',
56+
'jsx',
57+
'svelte',
58+
'ts',
59+
'tsx',
60+
'vue',
61+
62+
],
63+
3464
/*
3565
|--------------------------------------------------------------------------
3666
| Testing
@@ -41,29 +71,16 @@
4171
| attempts to locate the component as a file relative to any of the
4272
| paths AND with any of the extensions specified here.
4373
|
74+
| By default, it uses the `page_paths` and `page_extensions` settings
75+
| defined above. You may override these values for testing purposes
76+
| by adding these two keys to this `testing` array.
77+
|
4478
*/
4579

4680
'testing' => [
4781

4882
'ensure_pages_exist' => true,
4983

50-
'page_paths' => [
51-
52-
resource_path('js/Pages'),
53-
54-
],
55-
56-
'page_extensions' => [
57-
58-
'js',
59-
'jsx',
60-
'svelte',
61-
'ts',
62-
'tsx',
63-
'vue',
64-
65-
],
66-
6784
],
6885

6986
'history' => [

src/ComponentNotFoundException.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
<?php
2+
3+
namespace Inertia;
4+
5+
use InvalidArgumentException;
6+
7+
class ComponentNotFoundException extends InvalidArgumentException {}

src/ResponseFactory.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
use Illuminate\Support\Facades\Response as BaseResponse;
1212
use Illuminate\Support\Traits\Macroable;
1313
use Inertia\Support\Header;
14+
use InvalidArgumentException;
1415
use Symfony\Component\HttpFoundation\RedirectResponse as SymfonyRedirect;
1516
use Symfony\Component\HttpFoundation\Response as SymfonyResponse;
1617

@@ -156,11 +157,27 @@ public function always($value): AlwaysProp
156157
return new AlwaysProp($value);
157158
}
158159

160+
/**
161+
* @throws ComponentNotFoundException
162+
*/
163+
protected function findComponentOrFail(string $component): void
164+
{
165+
try {
166+
app('inertia.view-finder')->find($component);
167+
} catch (InvalidArgumentException) {
168+
throw new ComponentNotFoundException("Inertia page component [{$component}] not found.");
169+
}
170+
}
171+
159172
/**
160173
* @param array|Arrayable $props
161174
*/
162175
public function render(string $component, $props = []): Response
163176
{
177+
if (config('inertia.ensure_pages_exist', false)) {
178+
$this->findComponentOrFail($component);
179+
}
180+
164181
if ($props instanceof Arrayable) {
165182
$props = $props->toArray();
166183
}

src/ServiceProvider.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,11 +32,19 @@ public function register(): void
3232
$this->registerTestingMacros();
3333
$this->registerMiddleware();
3434

35+
$this->app->bind('inertia.view-finder', function ($app) {
36+
return new FileViewFinder(
37+
$app['files'],
38+
$app['config']->get('inertia.page_paths'),
39+
$app['config']->get('inertia.page_extensions')
40+
);
41+
});
42+
3543
$this->app->bind('inertia.testing.view-finder', function ($app) {
3644
return new FileViewFinder(
3745
$app['files'],
38-
$app['config']->get('inertia.testing.page_paths'),
39-
$app['config']->get('inertia.testing.page_extensions')
46+
$app['config']->get('inertia.testing.page_paths', fn () => $app['config']->get('inertia.page_paths')),
47+
$app['config']->get('inertia.testing.page_extensions', fn () => $app['config']->get('inertia.page_extensions'))
4048
);
4149
});
4250
}

tests/ResponseFactoryTest.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
use Illuminate\Support\Facades\Request;
1313
use Illuminate\Support\Facades\Route;
1414
use Inertia\AlwaysProp;
15+
use Inertia\ComponentNotFoundException;
1516
use Inertia\DeferProp;
1617
use Inertia\Inertia;
1718
use Inertia\LazyProp;
@@ -376,4 +377,22 @@ public function toArray()
376377
],
377378
]);
378379
}
380+
381+
public function test_will_throw_exception_if_component_does_not_exist_when_ensuring_is_enabled(): void
382+
{
383+
config()->set('inertia.ensure_pages_exist', true);
384+
385+
$this->expectException(ComponentNotFoundException::class);
386+
$this->expectExceptionMessage('Inertia page component [foo] not found.');
387+
388+
(new ResponseFactory)->render('foo');
389+
}
390+
391+
public function test_will_not_throw_exception_if_component_does_not_exist_when_ensuring_is_disabled(): void
392+
{
393+
config()->set('inertia.ensure_pages_exist', false);
394+
395+
$response = (new ResponseFactory)->render('foo');
396+
$this->assertInstanceOf(\Inertia\Response::class, $response);
397+
}
379398
}

0 commit comments

Comments
 (0)