# Instalação do Laravel 8 SPA com o Inertia.js, Vue.js 3 & Twitter Bootstrap 5 ###### tags: `laravel` `inertiajs` `vuejs` `twitter bootstrap` <div style="text-align:center"> <img src="https://i.imgur.com/nEvh0v6.png" /> </div> <br /> <div style="text-align:center"> <img src="https://i.imgur.com/qTgoGI6.gif" /> </div> ## Composer Para começar é necessário ter o [composer](https://getcomposer.org) instalado. Baixe ele [aqui](https://getcomposer.org/download/), em seguida(opcional): ```shell sudo mv composer.phar /usr/local/bin/composer ``` ## Laravel ### Instalação #### Primeiro vamos criar um novo projeto novo: ```shell composer create-project laravel/laravel --prefer-dist site cd site ``` ### Configuração Cria o banco de dados: ```shell touch database/database.sqlite ``` Conteúdo do arquivo `.env` ```ini APP_NAME="Seu Site" APP_ENV=local APP_KEY= APP_DEBUG=true APP_URL=http://site.com.br LOG_CHANNEL=stack LOG_LEVEL=debug DB_CONNECTION=sqlite BROADCAST_DRIVER=log CACHE_DRIVER=file FILESYSTEM_DRIVER=local QUEUE_CONNECTION=sync SESSION_DRIVER=file SESSION_LIFETIME=120 MEMCACHED_HOST=127.0.0.1 REDIS_HOST=127.0.0.1 REDIS_PASSWORD=null REDIS_PORT=6379 MAIL_MAILER=smtp MAIL_HOST=mailhog MAIL_PORT=1025 MAIL_USERNAME=null MAIL_PASSWORD=null MAIL_ENCRYPTION=null MAIL_FROM_ADDRESS=null MAIL_FROM_NAME="${APP_NAME}" AWS_ACCESS_KEY_ID= AWS_SECRET_ACCESS_KEY= AWS_DEFAULT_REGION=us-east-1 AWS_BUCKET= AWS_USE_PATH_STYLE_ENDPOINT=false PUSHER_APP_ID= PUSHER_APP_KEY= PUSHER_APP_SECRET= PUSHER_APP_CLUSTER=mt1 MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}" MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}" ``` Crie um [novo repositório](https://github.com/new) no [Github](https://github.com) para manter um histórico de alterações, depois inicialize o git: ```shell git init git add . git commit -m "Laravel 8" git branch -M main git remote add origin git@github.com:seu_login/site.git git push -u origin main ``` *Altere **seu_login** e **site** para os respectivos login e repositório criados no Github.* Para enviar o conteúdo da sua pasta local para o Github é necessário cadastrar sua chave SSH nas configurações da conta no Github, se tiver dúvidas de como fazer isso deixe um comentário neste artigo. ## Inertia.js ### Lado servidor: #### Instalação ```shell composer require inertiajs/inertia-laravel php artisan inertia:middleware ``` #### Configuração No arquivo `app/Http/Kernel.php` dentro de `$middlewareGroups` na última linha da chave `web` adicione a seguinte linha: ```php \App\Http\Middleware\HandleInertiaRequests::class, ``` Conteudo do arquivo `app/Http/Middleware/HandleInertiaRequests.php`: ```php <?php namespace App\Http\Middleware; use Illuminate\Http\Request; use Inertia\Middleware; class HandleInertiaRequests extends Middleware { /** * The root template that's loaded on the first page visit. * * @see https://inertiajs.com/server-side-setup#root-template * @var string */ protected $rootView = 'app'; /** * Determines the current asset version. * * @see https://inertiajs.com/asset-versioning * @param \Illuminate\Http\Request $request * @return string|null */ public function version(Request $request) { return parent::version($request); } /** * Defines the props that are shared by default. * * @see https://inertiajs.com/shared-data * @param \Illuminate\Http\Request $request * @return array */ public function share(Request $request) { return array_merge(parent::share($request), [ 'appName' => config('app.name'), 'assetUrl' => config('app.asset_url'), 'user' => fn () => $request->user() ? $request->user()->only('id', 'name', 'email') : null ]); } } ``` ### Lado cliente: #### Instalação ```shell npm install @inertiajs/inertia @inertiajs/inertia-vue3 ``` ### Blade Conteúdo do arquivo `resources/views/app.blade.php` ```html <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0" /> <link href="{{ mix('/css/app.css') }}" rel="stylesheet" /> @routes <script src="{{ mix('/js/app.js') }}" defer></script> </head> <body> @inertia </body> </html> ``` Salve as alterações no Github, se algo der errado você pode voltar o estado do seu projeto para antes das alterações: ``` git add . git commit -m "Inertia.js" git push ``` ## Ziggy ### Instalação O Ziggy serve para expor suas rotas existentes no lado servidor(Laravel) para o lado cliente(Vue.js): ```shell composer require tightenco/ziggy php artisan ziggy:generate git add . git commit -m "Ziggy.js" git push ``` ## Vue.js 3 ### Instalação ```shell npm install vue@next ``` ### Configuração #### Layouts e Componentes - Arquivo `resources/js/Layouts/Main.vue` [Link](https://paste.laravel.io/cd8d7ea2-3767-41bc-8715-2ab2b57f3e4f/raw) - Arquivo `resources/js/Components/Header.vue` [Link](https://paste.laravel.io/06cd5e3e-ad0b-4a22-a8c0-bff8fddef484/raw) - Arquivo `resources/js/Components/Footer.vue` [Link](https://paste.laravel.io/ecb14efe-ee80-4a81-9c6f-7c390cdd9f43/raw) - Arquivo `resources/js/Components/Carousel.vue` [Link](https://paste.laravel.io/a496a7fc-ad1b-49b1-b431-e542d767ee29/raw) #### Páginas - Arquivo `resources/js/Pages/Index.vue` [Link](https://paste.laravel.io/9ba16ac5-7ece-4282-a214-a26756bc15c1/raw) - Arquivo `resources/js/Pages/About.vue` [Link](https://paste.laravel.io/52eaff0a-7ede-46b4-ad0a-0dc39e688a85/raw) #### Login e Cadastro - Login `resources/js/Pages/Auth/Login.vue` [Link](https://paste.laravel.io/de83eb3a-0d00-4462-b349-9b29b8e1a8d0/raw) - Cadastro `resources/js/Pages/Auth/Register.vue` [Link](https://paste.laravel.io/38b78bb0-c419-4f76-83ee-89b12e686956/raw) #### Arquivos de Estilo - [resources/css/signin.css](https://getbootstrap.com/docs/5.1/examples/sign-in/signin.css) - [resources/css/carousel.css](https://getbootstrap.com/docs/5.1/examples/carousel/carousel.css) ## Laravel Mix Conteúdo do arquivo `webpack.mix.js` ```jsx const mix = require('laravel-mix'); const path = require('path'); mix.js('resources/js/app.js', 'public/js') .vue({ version: 3 }) .sass('resources/scss/app.scss', 'public/css') .webpackConfig((webpack) => { return { resolve: { alias: { '@': path.resolve('resources/js'), vue: path.resolve('node_modules', 'vue'), ziggy: path.resolve('vendor/tightenco/ziggy/dist/vue') } }, plugins: [ new webpack.DefinePlugin({ __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false }), ] } }) if(process.env.NODE_ENV == 'development') { mix.sourceMaps() } if(process.env.NODE_ENV == 'production') { mix.version() } ``` ## app.js Conteúdo do arquivo `resources/js/app.js` ```jsx require('./bootstrap'); import { createApp, h } from 'vue' import { createInertiaApp } from '@inertiajs/inertia-vue3' import { ZiggyVue } from 'ziggy'; import { Ziggy } from './ziggy'; // Twitter Bootstrap import 'bootstrap' import BaseLayout from '@/Layouts/Main' createInertiaApp({ resolve: name => { const page = require(`./Pages/${name}`).default page.layout = page.layout || BaseLayout return page }, setup({ el, app, props, plugin }) { createApp({ render: () => h(app, props) }) .mixin({ methods: { route } }) .use(plugin, ZiggyVue, Ziggy) .mount(el) }, }) ``` ## Laravel Fortify ### Instalação ```shell composer require laravel/fortify php artisan vendor:publish --provider="Laravel\Fortify\FortifyServiceProvider" php artisan migrate # (opcional, deixe para fazer o migrate depois...) ``` ### Configuração No arquivo `config/app.php` dentro do array `providers` adicione na última linha de `Application Service Providers` o seguinte conteúdo: ```php App\Providers\FortifyServiceProvider::class, ``` Abra o arquivo `app/Providers/FortifyServiceProvider.php` e no topo, logo abaixo da linha que começa com `namespace` adicione: ``` use Inertia\Inertia; ``` E abaixo, dentro do método `boot()` adicione o seguinte código no final do método: ```php Fortify::registerView(function() { return Inertia::render('Auth/Register'); }); Fortify::loginView(function() { return Inertia::render('Auth/Login'); }); ``` Git commit: ``` git add . git commit -m "Laravel Fortify" git push ``` ## Laravel Sanctum ### Instalação ```shell composer require laravel/sanctum php artisan vendor:publish --provider="Laravel\Sanctum\SanctumServiceProvider" php artisan migrate ``` ### Configuração Abra o arquivo `app/Models/User.php` e abaixo da linha que começa com `namespace` adicione a seguinte linha: ```php use Laravel\Sanctum\HasApiTokens; ``` No mesmo arquivo na linha que contem: ```php use HasFactory, Notifiable; ``` Adicione `HasApiTokens` assim: ```php use HasApiTokens, HasFactory, Notifiable; ``` Salve o estado atual da aplicação: ``` git add . git commit -m "Laravel Sanctum" git push ``` ## Twitter Bootstrap 5 ### Instalação ```shell npm install bootstrap npm install @popperjs/core ``` ### Configuração Crie o arquivo `resources/scss/app.scss` com o seguinte conteúdo: ```sass @import url('https://fonts.googleapis.com/css?family=Nunito'); html, body { height: 100%; margin: 0; } body { font-family: 'Nunito', sans-serif; padding-top: 3.5rem; } #app { display: flex; flex-direction: column; height: 100%; margin: 0; } @import '~bootstrap/scss/bootstrap'; ``` ## Rotas #### Configuração No edite o arquivo `routes/web.php` para se parecer com este trecho de código: ```php <?php use Inertia\Inertia; use Illuminate\Support\Facades\Route; Route::inertia('/', 'Index')->name('welcome'); Route::inertia('/sobre', 'About'); Route::inertia('/contato', 'Contact'); Route::middleware('auth:sanctum')->group(function() { Route::get('/dashboard', function() { return Inertia::render('Admin/Dashboard'); })->name('dashboard'); }); ``` ## Configurações finais No arquivo `app/Providers/RouteServiceProvider.php` altere a linha: ``` public const HOME = '/home'; ``` Para: ``` public const HOME = '/'; ``` ## Teste Abra duas abas do terminal e rode os comandos: ``` php artisan serve npm run watch # 2 vezes ``` Agora visite http://127.0.0.1:8000 e teste as rotas. Espero que funcione. Forte abraço. ## Repositório Se preferir, pode clonar o repositório deste projeto no Github: - https://github.com/sistematico/livb ## Vídeo de demonstração - [Vimeo](https://vimeo.com/584472057) ## Fontes - [Laravel](https://laravel.com/docs/8.x) - [Vue.js](https://v3.vuejs.org/guide/introduction.html) - [Inertia.js](https://inertiajs.com/) - [Laracasts](https://laracasts.com) - [Designated Coder](https://www.youtube.com/channel/UCGRi3eupIN5rOP_tDLxLs2w) - [Grupo PHP Brasil](https://t.me/phpbr) - [Grupo Laravel Brasil](https://t.me/laravelbr) - [Grupo VueJS Brasil](https://t.me/vuejsbr) - [Grupo JavaScript Brasil](https://t.me/javascriptbr) ## Ajude Se esse artigo foi útil pra você de alguma maneira(eu espero que sim :grinning:) considere doar um valor simbólico ou me patrocinar para que eu possa ajudar sempre mais. [![LiberaPay](https://img.shields.io/badge/LiberaPay-gray?logo=liberapay&logoColor=white&style=flat-square)](https://liberapay.com/sistematico/donate) [![PagSeguro](https://img.shields.io/badge/PagSeguro-gray?logo=pagseguro&logoColor=white&style=flat-square)](https://pag.ae/bfxkQW) [![ko-fi](https://img.shields.io/badge/ko--fi-gray?logo=ko-fi&logoColor=white&style=flat-square)](https://ko-fi.com/K3K32RES9) [![Buy Me a Coffee](https://img.shields.io/badge/Buy_Me_a_Coffee-gray?logo=buy-me-a-coffee&logoColor=white&style=flat-square)](https://www.buymeacoffee.com/sistematico) [![Open Collective](https://img.shields.io/badge/Open_Collective-gray?logo=opencollective&logoColor=white&style=flat-square)](https://opencollective.com/sistematico) [![Patreon](https://img.shields.io/badge/Patreon-gray?logo=patreon&logoColor=white&style=flat-square)](https://patreon.com/sistematico) ![GitHub Sponsors](https://img.shields.io/github/sponsors/sistematico?label=Github%20Sponsors)