'Vuejs and laravel - Template should only be responsible for mapping the state of the UI

There's some part of my project where i have some vuejs content inside of a blade template of course. But it gives me this error: " Templates should only be responsible for mapping the state to the UI. Avoid placing tags with side-effects in your templates, such as , as they will not be parsed."

vue-laravel-stripe

My app.js:

/**
 * First we will load all of this project's JavaScript dependencies which
 * includes Vue and other libraries. It is a great starting point when
 * building robust, powerful web applications using Vue and Laravel.
 */

require('./bootstrap');
window.Vue = require('vue');

/**
 * Next, we will create a fresh Vue application instance and attach it to
 * the page. Then, you may begin adding components to this application
 * or customize the JavaScript scaffolding to fit your unique needs.
 */

import StripeForm from './components/StripeForm';
Vue.component('stripe-form', StripeForm);
const app = new Vue({
    el: '#app'
});

My app.blade template:

<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <!-- CSRF Token -->
    <meta name="csrf-token" content="{{ csrf_token() }}">

    <title>{{ config('app.name', 'Laravel') }}</title>

    <!-- Scripts -->
    <script src="{{ asset('js/app.js') }}" defer></script>

    <!-- Fonts -->
    <link rel="dns-prefetch" href="https://fonts.gstatic.com">
    <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
    <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Slabo+27px">


    <!-- Styles -->
    <link href="{{ asset('css/app.css') }}" rel="stylesheet">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.3.1/css/all.css"
          integrity="sha384-mzrmE5qonljUremFsqc01SB46JvROS7bZs3IO2EmfFsd15uHvIt+Y8vEf7N7fWAU" crossorigin="anonymous">
    @stack('styles')
</head>
<body>

@include('partials.navigation')
@yield('jumbotron')
<div id="app">
    <main class="py-4">
        @if(session('message'))
            <div class="row justify-content-center">
                <div class="col-md-10">
                    <div class="alert alert-{{session('message')[0]}}">
                        <h4 class="alert-heading">
                            {{ __("Mensaje informativo") }}
                        </h4>
                        <p>{{session('message')[1]}}</p>
                    </div>
                </div>
            </div>
        @endif
        @yield('content')
    </main>
</div>
<script src="{{ asset('js/app.js') }}"></script>

</body>
</html>

Here's my vue-component:

<template>
    <stripe-checkout
            button="Suscribirme"
            buttonClass="btn btn-course"
            :stripe-key="stripe_key"
            :product="product"
    >
    </stripe-checkout>
</template>

<script>
    import {StripeCheckout} from 'vue-stripe';

    export default {
        components: {
            StripeCheckout
        },
        // name: "stripe-form",
        props: {
            stripe_key: '',
            name: '',
            amount: '',
            description: ''
        },
        computed: {
            product() {
                return {
                    name: this.name,
                    amount: parseFloat(this.amount),
                    description: this.description
                }
            }
        }
    }
</script>

Here's where i have it as one of my partials:

<form action="{{ route('subscriptions.process_subscription') }}" method="POST">
    @csrf
    <input
            class="form-control"
            name="coupon"
            placeholder="{{ __("¿Tienes un cupón?") }}"
    />
    <input type="hidden" name="type" value="{{ $product['type'] }}"/>
    <hr/>
    <stripe-form
            stripe_key="{{ env('STRIPE_KEY') }}"
            name="{{ $product['name'] }}"
            amount="{{ $product['amount'] }}"
            description="{{ $product['description'] }}"
    ></stripe-form>
</form>

And here i include it on a template:

@extends('layouts.app')

@push('styles')
    <link rel="stylesheet" href="{{ asset('css/pricing.css') }}">
@endpush


@section('jumbotron')
    @include('partials.jumbotron', [
        'title' => __("Subscríbete ahora a uno de nuestros planes"),
        'icon' => 'globe'
    ])
@endsection

@section('content')
    <div class="container">
        <div class="pricing-table pricing-three-column row">
            <div class="plan col-sm-4 col-lg-4">
                <div class="plan-name-bronze">
                    <h2>{{ __("MENSUAL") }}</h2>
                    <span>{{ __(":price / Mes", ['price' => '€ 9,99']) }}</span>
                </div>
                <ul>
                    <li class="plan-feature">{{ __("Acceso a todos los cursos") }}</li>
                    <li class="plan-feature">{{ __("Acceso a todos los archivos") }}</li>
                    <li class="plan-feature">
                            @include('partials.stripe.form', [
                            "product" => [
                                "name" => __("Suscripción"),
                                "description" => __("Mensual"),
                                "type" => "monthly",
                                "amount" => 999,99
                            ]
                        ])
                    </li>
                </ul>
            </div>

            <div class="plan col-sm-4 col-lg-4">
                <div class="plan-name-silver">
                    <h2>{{ __("Trimestral") }}</h2>
                    <span>{{ __(":price / 3 meses", ['price' => '€ 19,99']) }}</span>
                </div>
                <ul>
                    <li class="plan-feature">{{ __("Acceso a todos los cursos") }}</li>
                    <li class="plan-feature">{{ __("Acceso a todos los archivos") }}</li>
                    <li class="plan-feature">
                            @include('partials.stripe.form',
                           ["product" => [
                               'name' => 'Suscripción',
                               'description' => 'Trimestral',
                               'type' => 'quarterly',
                               'amount' => 1999.99
                           ]]
                       )
                    </li>
                </ul>
            </div>

            <div class="plan col-sm-4 col-lg-4">
                <div class="plan-name-gold">
                    <h2>{{ __("ANUAL") }}</h2>
                    <span>{{ __(":price / 12 meses", ['price' => '€ 89,99']) }}</span>
                </div>
                <ul>
                    <li class="plan-feature">{{ __("Acceso a todos los cursos") }}</li>
                    <li class="plan-feature">{{ __("Acceso a todos los archivos") }}</li>
                    <li class="plan-feature">
                            @include('partials.stripe.form',
                            ["product" => [
                                'name' => 'Suscripción',
                                'description' => 'Anual',
                                'type' => 'yearly',
                                'amount' => 8999.99
                            ]]
                        )
                    </li>
                </ul>
            </div>
        </div>
    </div>
@endsection

Notes: I've changed the script outside to inside the body tag and the opposite, and nothing, checked the tags and nothing



Solution 1:[1]

This library is injecting the script into your form. You can see the logic at this line

It's looping your scripts to determine if you load the library externally, and if not it's appending it to your form:

if(!scriptExists) {
    document.querySelector("#"+this.formId).appendChild(el);
}

So the way to solve it is to simply include it on the page yourself:

<script src="https://checkout.stripe.com/checkout.js"></script>

Which will prevent it from injecting the script into the form and will stop the VNODE from complaining about the presence of <script></script> tags in it.

Solution 2:[2]

For many users, this is due to them not closing all their HTML-tags correctly. It did the trick for me and many others: https://github.com/vuejs/vue-loader/issues/302

Solution 3:[3]

try closing out your HTML by adding just before your @endsection. Vue is trying to parse with your script as Vue is initialized on the wrapper, it will throw errors, as the page is mixed with scripts.

add and see if that solves your problem

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1
Solution 2 atra
Solution 3 Bret Johnson