Subdomains Laravel Routing and Vue.js - subdomain

I'm using Laravel 5.4, vue.js 2.3 and vue-router.
Current situation
When example.com is hit, Laravel returns the app view which starts the Vue.app
web.php
Route::get('/', function () {
return view('app');
});
app.js
const routes = [
{ path: '/', component: App },
];
const app = new Vue({
el: '#app',
router,
data () {
return {}
},
});
App.vue
export default {
...
}
What I'm trying to do
If usa.example.com is typed, I would like the alert() in my App.vue to show usa.
If italy.example.com is typed, I would like the alert() in my App.vue to show italy.
I read the documentation of vue-router but I'm not sure wether it is a Laravel issue, a Vue issue or both.
App.vue
export default {
....
created() {
alert('subdomain is ' + $route.params.subdomain)
}
}

VueRouter doesn't keep track of the subdomain.
But, you can get the subdomain from the location and use that in your component's created method:
created() {
let subdomain = location.hostname.split('.').shift();
alert('subdomain is ' + subdomain);
}
The above code is based off of this answer.

Related

Vue.js: Failed to generate render function

I try to run a simple Vue.js, but I constantly receive the following error:
[Vue warn]: It seems you are using the standalone build of Vue.js in
an environment with Content Security Policy that prohibits
unsafe-eval. The template compiler cannot work in this environment.
Consider relaxing the policy to allow unsafe-eval or pre-compiling
your templates into render functions.
main.js:3180 [Vue warn]: Failed to generate render function:
EvalError: Refused to evaluate a string as JavaScript because
'unsafe-eval' is not an allowed source of script in the following
Content Security Policy directive: "default-src 'self'". in
with(this){return _c('div',{attrs:{"id":"app"}})}
(found in )
Yet, I can't understand what is causing this error. I don't seem to use any dynamic templates and everything should be pre-compiled. Here is the code of my application:
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = Vue.component('home-component', {
render() {
return <div>
<router-link to="/users">Users</router-link>
<router-link to="/about">About</router-link>
</div>
}
})
const Users = Vue.component('users-component', {
render() {
return <p>Users</p>
}
})
const NotFound = Vue.component('not-found-component', {
render() {
return <p>Not Found</p>
}
})
const routes = [
{ path: '/', component: Home },
{ path: '/users', component: Users }
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')
And here is how I process JavaScript files in my gulpfile:
const paths = {
main: 'web/javascript/src/main.js',
allJs: 'web/javascript/**/*.{js,vue}',
resultJs: 'public/assets/javascript/main.js',
};
gulp.task('scripts', function() {
return browserify(paths.main)
.transform(babelify, { presets: ['es2015'], plugins: ["transform-runtime"] })
.transform(vueify)
.bundle()
.pipe(fs.createWriteStream(paths.resultJs))
}
There are seem to be many similar questions on StackOverflow, but none of them helped me.
The broweser is throwing Content Security Policy (CSP) error, to get around this issue you should consider switching to the runtime-only build, which is fully CSP-compliant.
https://v2.vuejs.org/v2/guide/installation.html#CSP-environments
Also, You have return incorrectly written. It should return jsx in pair of paranthesis (). The code below should help
import Vue from 'vue'
import VueRouter from 'vue-router'
const Home = Vue.component('home-component', {
render(h) {
return(
<div>
<router-link to="/users">Users</router-link>
<router-link to="/about">About</router-link>
</div>
)
}
})
const Users = Vue.component('users-component', {
render(h) {
return(
<p>Users</p>
)
}
})
const NotFound = Vue.component('not-found-component', {
render(h) {
return(
<p>Not Found</p>
)
}
})
const routes = [
{ path: '/', component: Home },
{ path: '/users', component: Users }
]
const router = new VueRouter({
routes
})
const app = new Vue({
router
}).$mount('#app')

How to bulid Application template Vue

I'm new to Vue and to ES6
And I did the following:
import Vue from 'vue'
import VueRouter from 'vue-router'
import $ from 'jquery'
Vue.use(VueRouter)
var App = {};
App.template = `
<main-menu></main-menu>
<router-view></router-view>`;
const header = Vue.component('main-menu', require('./components/app/header.vue'));
const facebook = Vue.component('facebook-gif', require('./components/facebook.vue'));
const router = new VueRouter({
routes: [
{
path: '/',
},
{
path: '/facebook',
component: {
facebook: facebook
}
}
]
});
App.app = new Vue({
router,
render (h) {
return h(`div`, App.template)
}
}).$mount('#app');
But what it's nothing render , I just see the main-menu and router-view tags in my broswer...
And when I edit my html and put there this:
<div id="app">
<main-menu></main-menu>
<router-view></router-view>
</div>
I get this error when I'm trying to enter the facebook route:
[Vue warn]: Failed to mount component: template or render function not defined.
and the facebook template is wrapped with template tag and it's inside a vue file
facebook.vue
<template>
<div>
dsfsdsfdsf
<div v-if="showLogin">
<button v-on:click="login">Log In With Facebook</button>
<span v-if="error">{{ error }}</span>
</div>
</div>
</template>
<script>
export default {
data() {
return {
showLogin: true,
error:null,
}
},
methods() {
return {
login() {
}
}
}
}
</script>
But the main-menu component is render...
What is the problem?
EDIT
I downloaded the example like wostex said
I create an App.vue file contain:
<template>
<div id="app">
<main-menu></main-menu>
<router-view></router-view>
</div>
</template>
I edit my html file to contain
I added in app.js
import App from './components/App.vue'
const v = new Vue({
el: "#app",
router,
render: h => h(App)
});
and my html file contain:
<div id="app"></div>
and I get this error:
vue.common.js:436 [Vue warn]: Failed to mount component: template or render function not defined.
found in
---> <Anonymous>
<App> at /opt/lampp/htdocs/gif/resources/assets/js/components/App.vue
<Root>
it happens because the facebook component, when I'm in the main page I don't see the error, only when I enter the facebook route
It seems your first set up was failing because of what build you we're using. For eg:
App.app = new Vue({
router,
render (h) {
return h(`div`, App.template) // this part can be roughly
// translated to `return h(`div`,
// `<one-component></one-component>
// <router-view></router-view>`)` and I believe
// this failed due to the fact that when you pass
// template string to the render method it needs to
// be compiled and your setup didn't account for that.
}
}).$mount('#app');
Your other set up ( as per suggestion of #wostex ) is much better but I think that here you are missing .$mount('#app') at the end of your Vue initialization. So:
const v = new Vue({
router,
render: h => h(App)
}).$mount('#app')
I looked at Laracasts in Jeffry tutorial about Vue
He did there like that:
const router = new VueRouter({
routes: [
{
path: '/',
},
{
path: '/facebook',
component: require('./components/facebook.vue')
}
]
});
and it work's
So thanks every one that tried to help me

VueJS and a static JSON endpoint without IDs

So I'm trying to create a VueJS application, and I was given a set of JSON objects that are retrievable through a .json endpoint.
I'll call them People. So I get an array of people in this.people after using VueResource.
I'm able to iterate and get all the name displayed on the side, however, since its not an API nor has unique IDs minus their array indexes, I am having trouble trying to narrow down each object and create a single Person view page.
Hence if it was a normal api, I could do '/people/:id', but I can't. I'm also wondering if I may have stored the Prop/Component correctly.
I put together a quick example of how this might work with the Star Wars API.
const Loading = {
template: `<h1>Loading...</h1>`
};
const People = {
props: ["people"],
template: `
<div>
<h1>People</h1>
<ul>
<li v-for="person in people">
<router-link :to='{name: "person", params:{person: person}}'>{{person.name}}</router-link>
</li>
</ul>
</div>
`
};
const PersonDetails = {
props: ["person"],
template: `
<div>
<h1>{{person.name}}</h1>
<div>Height: {{person.height}}</div>
<div>Mass: {{person.mass}}</div>
<div>Hair Color: {{person.hair_color}}</div>
<br/>
<router-link to="people">Back to people</router-link>
</div>
`
};
const routes = [
{ path:"/", component: Loading},
{ path: "/people", name: "people", component: People},
{ path: "/person", name: "person", component: PersonDetails, props: true},
]
const router = new VueRouter({
routes
})
new Vue({
el: "#app",
router,
data:{
people:[]
},
mounted(){
this.$axios.get("https://swapi.co/api/people/")
.then((response) => {
this.people = response.data.results
this.$router.push("people")
})
}
});
Here is the working example.

Using indexRedirect in a route configuration object

I was wondering if it's possible to use "indexRedirect" in a route configuration object (so without using JSX).
I tried without success, so I assumed that this isn't supported at the moment, but then my issue (https://github.com/reactjs/react-router/issues/3150) was closed without comment, so I still don't know if it's because the feature is already there but I misuse it, or because this is a unwanted feature.
Thanks in advance. :)
As described in the docs, the equivalent to indexRedirect using a plain configuration object looks like this
const routes = [{
path: '/',
component: App,
indexRoute: { onEnter: (nextState, replace) => replace('/welcome') },
childRoutes: [
{ path: 'welcome', component: Welcome },
{ path: 'about', component: About }
]
}]
Using plain routes config it's a bit more low level API, and there is no point of having special redirect or indexRedirect keys in the routes object. Instead you could use onEnter to accomplish a redirect. Here is how:
import React from 'react'
import { render } from 'react-dom';
import { Router, browserHistory } from 'react-router'
const Home = () => <h3>Home</h3>
const About = () => <h3>About</h3>
const routes = [{
path: '/',
component: Home,
onEnter: (nextState, replace) => replace('/about')
}, {
path: '/about',
component: About
}]
render(
<Router history={browserHistory} routes={routes} />,
document.getElementById('root')
);
Edit: added this into docs as well.
I would appreciate the same thing as JGX: working relative paths for this kind of redirecting

URL in web api and angularjs

in visual studio 2013 i have setup a web api project and added an index.html page with angularjs framework: why, when i run the project, the url is
http://localhost:49375/index.html#/
How can i remove the index.hmtl# for the root page?
In angularjs i have the following route:
gestionale.config(['$routeProvider',
function ($routeProvider) {
$routeProvider.
when('/', {
templateUrl: 'View/people.html',
controller: 'mainController'
});
}]);
and in the WebApiConfig.cs:
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
I think you refer to:
$locationProvider.html5Mode(true);
It is use something like this:
angular.module('demoApp',['ngRoute'],function ($routeProvider, $locationProvider)
{
$locationProvider.html5Mode(true);
$routeProvider.
when('/',{
...
It basically lets you use angular routing without the # prefix character.