How to change initially generated title after file build in index.html - vuejs2

I have downloaded a vue.js template from the web. Whenever I build files via npm the title on the index.html keeps being swapped to the name of the template. Is there a way to change the default title?

As I understand your question - you need to configure your vue.config.js file something like this (pay attention on Webpack part) - these files are from working project, so you have maximum understanding on how it could look at the end:
module.exports = {
baseUrl: '/',
outputDir: (process.env.NODE_ENV === 'production' ? '../web/' : '../web/js/'),
indexPath: '../app/Resources/views/index.html.twig',
// Setting this to false can speed up production builds if you don't need source maps for production.
productionSourceMap: false,
// By default, generated static assets contains hashes in their filenames for better caching control.
// However, this requires the index HTML to be auto-generated by Vue CLI. If you cannot make use of the index HTML
// generated by Vue CLI, you can disable filename hashing by setting this option to false,
filenameHashing: false,
lintOnSave: false,
// https://cli.vuejs.org/ru/config/#devserver-proxy
devServer: {},
// https://cli.vuejs.org/ru/config/#chainwebpack
chainWebpack: config => {
config
.plugin('html')
.tap(args => {
args[0].title = 'Ojok Deep Sales Platform';
args[0].template = './index.html.template';
return args;
})
}
};
And after you have updated your vue.config.js file, change your index.html template file to be like this:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<title><%= htmlWebpackPlugin.options.title %></title>
<link href='https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900' rel="stylesheet">
<link href="https://fonts.googleapis.com/css?family=Material+Icons" rel="stylesheet">
<script type="text/javascript" src="../js/go.js"></script>
<script type="text/javascript" src="../js/momentjs.js"></script>
<script type="text/javascript" src="../js/webphone/flashphoner.js"></script>
<script type="text/javascript" src="../js/webphone/SoundControl.js"></script>
</head>
<body>
<div id="app"></div>
</body>
</html>
Pay attention on what is being included in <title>-tag:
<title><%= htmlWebpackPlugin.options.title %></title>
After generating new index.html file your title should be set to whatever you have written into args[0].title option.
Hope this helps.

I'm still new at VueJS, but here were my findings. I'd love any suggested options or improvements. I went with option #2.
Option 1: set for Multiple Pages mode
vue.config.js
module.exports = {
pages: {
index: {
entry: 'src/main.js',
// template title tag needs to be <title><%= htmlWebpackPlugin.options.title %></title>
title: 'My Website Title',
},
}
}
Option 2: titleMixin (referenced from https://medium.com/#Taha_Shashtari/the-easy-way-to-change-page-title-in-vue-6caf05006863)
titleMixin.js added to mixins folder
function getTitle (vm) {
const { title } = vm.$options
if (title) {
return typeof title === 'function'
? title.call(vm)
: title
}
}
export default {
created () {
const title = getTitle(this)
if (title) {
document.title = title
}
}
}
added to main.js
import titleMixin from './mixins/titleMixin'
Vue.mixin(titleMixin)
Use in Component Pages
<script>
export default {
title: 'Foo Page'
}
</script>
Use in Vue instance with a function
<script>
export default {
title () {
return `Foo Page — ${this.someValue}`
},
data () {
return {
someValue: 'bar'
}
}
}
</script>

Option 1:
Edit your /public/index.html and replace this:
<title><%= htmlWebpackPlugin.options.title %></title>
with this:
<title>Your Title Here</title>
Option 2:
vue.config.js
module.exports = {
chainWebpack: config => {
config.plugin('html').tap(args => {
args[0].title = 'Your Title Here';
return args;
});
}
}
/public/index.html
<title><%= htmlWebpackPlugin.options.title %></title>

Related

How to export a quasar app as a web component

I am trying to build a quasar app as a web component, for which I am planning to use vue custom element.
I did the following changes,
import { boot } from 'quasar/wrappers';
import { defineCustomElement } from 'vue';
//#ts-ignore
import vueCustomElement from 'vue-custom-element';
import * as BaseApp from './../App.vue';
import { App } from "vue";
let custElement: any;
export default boot(({app,router,store}) => {
custElement = vueCustomElement;
//#ts-ignore
BaseApp.default.store = store;
//#ts-ignore
BaseApp.default.router = router;
const CustomElement = defineCustomElement({props:BaseApp.default.props,setup:BaseApp.default.setup,name:BaseApp.default.name,store:BaseApp.default.store,router:BaseApp.default.router})
customElements.define('test-app', CustomElement)
});
export { custElement };
Did the following changes in quasar.conf.js file to disable chunking
chainWebpack: (config) => {
config.resolve.symlinks(false);
config.optimization.splitChunks(false);
config.output.filename('js/app.js');
},
filenameHashing: false,
pluginOptions: {
webpackBundleAnalyzer: {
openAnalyzer: false,
},
},
configureWebpack: {
output: {
libraryExport: 'default',
},
devServer: {
disableHostCheck: true,
},
},
extendWebpack(cfg) {
cfg.plugins.push(
new webpack.optimize.LimitChunkCountPlugin({
maxChunks: 1,
})
);
const vueLoaderRule = cfg.module.rules
.find(el => el.test.toString() == /\.vue$/.toString())
const ruleFirstLoader = vueLoaderRule.use[0]
const options = ruleFirstLoader.options
// change options
options.transpileOptions = {
transforms: {
dangerousTaggedTemplateString: true
}
}
},
Added the custom element in the index.template.html file
<!DOCTYPE html>
<html>
<head>
<title><%= productName %></title>
<meta charset="utf-8">
<meta name="description" content="<%= productDescription %>">
<meta name="format-detection" content="telephone=no">
<meta name="msapplication-tap-highlight" content="no">
<meta name="viewport" content="user-scalable=no, initial-scale=1, maximum-scale=1, minimum-scale=1, width=device-width<% if (ctx.mode.cordova || ctx.mode.capacitor) { %>, viewport-fit=cover<% } %>">
<link rel="icon" type="image/png" sizes="128x128" href="icons/favicon-128x128.png">
<link rel="icon" type="image/png" sizes="96x96" href="icons/favicon-96x96.png">
<link rel="icon" type="image/png" sizes="32x32" href="icons/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="icons/favicon-16x16.png">
<link rel="icon" type="image/ico" href="favicon.ico">
</head>
<body>
<!-- DO NOT touch the following DIV -->
<!-- <div id="q-app"></div> -->
<test-app id="q-app"></test-app>
</body>
</html>
When running the app, the rendered html content will look like the below,
Rendered Vue Custom Element
I am not sure where the issue is. It would be grateful if I got any suggestions to solve this issue.
Thanks in advance for your help.

Lumen "The requested resource was not found on this server." Error

Problem: Images are not showing in Lumen-vue project.
This question may seems a bit long. But I tried to make it visual easily.
In my lumen(8.3.4) server, I'm using a standalone vue frontend, and delivering the compiled css & js in public/frontend folder. Here is my folder structure
As you can see the vue app is inside the frontend folder my vue.config.js setting is as following:
const path = require("path");
const chunkPrefix = '[name]'
module.exports = {
filenameHashing: false,
outputDir: path.resolve(__dirname, "../public/frontend"),
chainWebpack: (config) => {
config.module
.rule('images')
.use('url-loader')
.tap(options => Object.assign({}, options, {name: `${chunkPrefix}.[ext]`}));
config.plugins.delete('html')
config.plugins.delete('preload')
config.plugins.delete('prefetch')
},
css: {
extract: {
filename: `css/${chunkPrefix}.css`,
chunkFilename: `css/${chunkPrefix}.css`,
},
},
configureWebpack: {
output: {
filename: `js/${chunkPrefix}.js`,
chunkFilename: `js/${chunkPrefix}.js`,
}
},
}
this delivering the compiled js & css after npm run build in public folder as per following
my app.blade.php is
<head>
<link rel="stylesheet" href="{{url('frontend/css/app.css')}}">
<link rel="stylesheet" href="{{url('frontend/css/chunk-vendors.css')}}">
</head>
<body>
<div>
<div id="app"></div>
</div>
<script type="text/javascript" src="{{url('frontend/js/chunk-vendors.js')}}"></script>
<script type="text/javascript" src="{{url('frontend/js/app.js')}}"></script>
<script type="text/javascript" src="{{url('frontend/js/0.js')}}"></script>
</body>
Now the problem is after loading the page is browswer, some images are not loading
This is how the inspect showing in case of failed picture
<img src="/img/profile02.png" alt="profile picture" class="img">
and the working one is
<img src="data:image/png;base64,iVBORw0KGgoAAAANSU==" alt="whatsapp icon"">
My vue asset handing is as following.
Can't figure out why some images are not loading.

jsPDF is not defined

I'm trying to use jsPDF with Vue but I get a ReferenceError: jsPDF is not defined. See the snippet :
let jsPrint = () => {
const doc = new jsPDF()
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
<button onclick="jsPrint()">
print
</button>
The script is linked in the head tag :
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title><?= $site->title() ?> - <?= $page->title() ?></title>
<link rel="stylesheet" href="<?= url('assets') ?>/css/style.css">
<!--========== JSPDF ==========-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/jspdf/2.4.0/jspdf.umd.min.js"></script>
<!--========== VUE ==========-->
<!-- development version, includes helpful console warnings -->
<script src="<?= url('assets') ?>/js/libs/vue.js"></script>
<script src="<?= url('assets') ?>/js/app.js" type="module" defer></script>
</head>
Then in a component, I have a method that should be triggered on click on a button :
exportSimple: function() {
const doc = new jsPDF()
// const target = document.querySelector('#dialog-export-content')
// doc.html(target, {
// callback: function(doc) {
// doc.save()
// },
// x: 10,
// y: 10
// })
}
But i throws an error.
I tried alternative methods to link the library : local, npm, other sources like jspdf.es.min.js. Nothing works.
Any idea ?
Using CDN the jsPDF object is available as property of jspdf which is available globally :
const { jsPDF } = jspdf
let print = () => {
const doc = new jsPDF()
}

[Vue warn]: Failed to mount component: template or render function not defined, using Laravel 8

I'm trying to create a new project but I'm getting this error and I don't know why. I'm using Laravel 8, Vue and Inertia.js.
I'm not sure if these files are important but I'll add anyways
webpack.mix.js
const mix = require('laravel-mix');
const path = require('path');
mix.js('resources/js/app.js', 'public/js').vue({ version: 2 })
.sass('resources/sass/app.scss', 'public/css')
.webpackConfig({
output: { chunkFilename: 'js/[name].js?id=[chunkhash]' },
resolve: {
alias: {
vue$: 'vue/dist/vue.runtime.esm.js',
'#': path.resolve('resources/js'),
},
},
})
.babelConfig({
plugins: ['#babel/plugin-syntax-dynamic-import'],
})
.version();
app.js
import InertiaApp from '#inertiajs/inertia-vue'
import Vue from 'vue'
Vue.use(InertiaApp);
const app = document.getElementById('app');
app.setAttribute(':class',"{'loaded': loaded}");
new Vue({
render: h => h(InertiaApp, {
props: {
initialPage: JSON.parse(app.dataset.page),
resolveComponent: name => import(`#/Pages/${name}`).then(module => module.default),
},
data(){
return{
loaded:true
}
}
}),
}).$mount(app);
app.blade.php
<!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() }}">
<!-- Scripts -->
<script src="{{ asset('js/app.js') }}" defer></script>
<!-- Styles -->
<link href="{{ asset('css/app.css') }}" rel="stylesheet">
</head>
<body>
#inertia
</body>
</html>
Finally the page I'm trying to show Login.vue
<template>
<div>
<h1>Login</h1>
</div>
</template>
<script>
export default {
data() {
return {}
},
mounted() {
console.log('mounted');
}
}
</script>
I don't know why this is happening or how to fix it.
What am I doing wrong?

Import object js in vue and exclude this file from bundling

I start with the simple vue.js application. I have icons in base64 format and put all them as object in separately file icons.js. I want to import this object to the file globals.js as globals constant and use this constant in all places where I need icons. BUT, this file does not need to be bundled.
I have files icons.js, globals.js, main.js, App.vue.
icons.js:
export const iconsData =
{
"large": {
"2": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAA3CAYAAAD6+O8NAAAAGXRFWHRTb2Z0d2FyZQB",
"3": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAAAsTAAALEwE",
"777": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFgAAAAUCAYAAAAJD/ojAAAAGXRFWHRTb2Z0d2FyZQB"
},
"small": {
"2": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADsAAAARCAYAAABjEtTjAAAAGXRFWHRTb2Z0d2F",
"3": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAAqCAYAAAAJWvOwAAAAGXRFWHRTb2Z0d2Fy",
"777": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAqCAYAAADMKGkhAAAAGXRFWHRTb2Z0d2",
}
};
globals.js:
import { iconsData } from './assets/icons'
export const icons = {
getIcon: function (iconNumber) {
if (!iconsData.large[iconNumber]) {
return "";
} else {
return iconsData.large[iconNumber];
}
},
isIcon:function (iconNumber) {
return iconsData.large[iconNumber];
}
};
In my App.vue :
<template>
<div id="app">
<div v-for="channel in channels">
<div class="icon" >
<img v-if="icons.isIcon(channel.number)" :src="icons.getIcon(channel.number)" >
<div v-if="!icons.isIcon(channel.number)" class="channel-name">{{channel.name}}</div>
</div>
</div>
</div>
</template>
<script>
import {icons} from "./globals"
export default {
name: 'app',
components: {
},
data() {
return {
icons: icons,
}
},
}
</script>
I tried
1) Vue.js exclude settings file from being bundled - not work for me
2)Exclude json file from being bundled in Vue from official documentation my file is in assets, but if I put absolutely path in global.js
import { iconsData } from '/assets/icons' - application not compiled.
Maybe this not right - import icons as const global? What I can do to leave file icons.js separately?
I suppose you're using webpack to build as you've tagged the question with VueCLI. If you don't want the icon data to be bundled, then you need to include such hints to webpack that the icon data should reside in a separate chunk than your app bundle. Something like this should work:
const iconsData = import('./assets/icons').then(icons => icons.iconsData);
You can also customize what the chunk should be named. Let's say you want it to be named icons-data, then you can do this:
const iconsData = import(/* webpackChunkName: "icons-data" */ './assets/icons').then(icons => icons.iconsData);
solved the problem this way:
1) Delete from icons.js word export
const iconsData =
{
"large": {
"2": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAAA3CAYAAAD6+O8NAAAAGXRFWHRTb2Z0d2FyZQB",
"3": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAACXBIWXMAAAsTAAALEwE",
"777": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAFgAAAAUCAYAAAAJD/ojAAAAGXRFWHRTb2Z0d2FyZQB"
},
"small": {
"2": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADsAAAARCAYAAABjEtTjAAAAGXRFWHRTb2Z0d2F",
"3": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADkAAAAqCAYAAAAJWvOwAAAAGXRFWHRTb2Z0d2Fy",
"777": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAC4AAAAqCAYAAADMKGkhAAAAGXRFWHRTb2Z0d2",
}
};
2) Delete from globals.js import
export const icons = {
getIcon: function (iconNumber) {
if (!iconsData.large[iconNumber]) {
return "";
} else {
return iconsData.large[iconNumber];
}
},
isIcon:function (iconNumber) {
return iconsData.large[iconNumber];
}
};
3) Add to index.html referense to icons.js
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title>Icons</title>
<script type="text/javascript" src="<%= BASE_URL %>icons.js"></script>
</head>
<body>
<noscript>
<strong>We're sorry but egg doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
4) Copy file icons.js to the public folder and to the src root
How I understand - this way exclude the file from webpack in "old school" way. How to do this with webpack - I do not understand.