Render Laravel 7 component programmatically

Solution 1:

Try this, it works for me in laravel 8, and I checked data function exists in laravel 7

$field = new Input('name', 'My field');
$field->render()->with($field->data());

** data function include methods, properties and attributes of Component.

Solution 2:

Manually add variables to the view. Otherwise it won't work

I reported this but it's not considered an issue:

https://github.com/laravel/framework/issues/32429

Solution 3:

I use this, it also works with anonymous component. Put this in your helper file.

/**
 * Render a blade component.
 * @param string $name Component name, exclude component folder (i.e use "card" instead of "components.card")
 * @param array $props Component properties
 * @param array $attributes Component attributes
 * @return \Illuminate\Contracts\View\View
 */
function viewComponent($name, $props = [], $attributes = []) {
    $className = collect(explode('.', $name))->map(function($part) {
        return \Str::studly($part);
    })->join('\\');
    $className = "App\\View\\Components\\{$className}";
    if(class_exists($className)) {
        $reflection = (new \ReflectionClass($className))->getConstructor();
        $parameters = [];
        foreach ($reflection->getParameters() as $param) {
            $parameters[] = $props[$param->name] ?? $param->getDefaultValue();
        }
        $component = new $className(...$parameters);
        $component->withAttributes($attributes);
        return $component->render()->with($component->data());
    }

    $props['attributes'] = new \Illuminate\View\ComponentAttributeBag($attributes);
    return view("components.$name", $props);
}

Usage

viewComponent('input', [
    'name' => 'name',
    'title' => 'My Field',
]);

// if you want custom attribute
viewComponent('input', [
    'name' => 'name',
    'title' => 'My Field',
], [
    'autocomplete' => 'off',
    'data-custom' => 'custom attribute',
]);

Solution 4:

The last release (v.8.80) of Laravel should help you achieve what you're trying to do with the pull #40425

Blade::render('<x-input name="name" :title="$title" />', ['title' => __('My field')]);