Clean metaInfo SEO (#40)

* Clean metaInfo SEO

* fix path

Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
Chirag 2022-12-22 16:25:17 +05:30 committed by GitHub
parent 549506ab8f
commit 286b82b3ce
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
27 changed files with 128 additions and 156 deletions

27
resources/js/base.js vendored
View File

@ -4,36 +4,13 @@
import debounce from 'debounce'
export default {
computed: {
$crisp () {
return window.$crisp
}
},
metaInfo () {
const info = {
meta: this.metaTags ?? []
}
if (this.metaTitle) {
info.title = this.metaTitle
info.meta = [
...info.meta,
{ vmid: 'og:title', property: 'og:title', content: this.metaTitle },
{ vmid: 'twitter:title', property: 'twitter:title', content: this.metaTitle }
]
}
if (this.metaDescription) {
info.meta = [
...info.meta,
{ vmid: 'description', name: 'description', content: this.metaDescription },
{ vmid: 'og:description', property: 'og:description', content: this.metaDescription },
{ vmid: 'twitter:description', property: 'twitter:description', content: this.metaDescription }
]
}
return info
},
methods: {
/**
* Creates a debounced function that delays invoking a callback.

View File

@ -45,6 +45,7 @@ import Amplitude from './service/Amplitude'
import Crisp from './service/Crisp'
import StopImpersonation from './pages/StopImpersonation'
import Notifications from "./common/Notifications"
import SeoMeta from '../mixins/seo-meta'
// Load layout components dynamically.
const requireContext = require.context('~/layouts', false, /.*\.vue$/)
@ -70,7 +71,11 @@ export default {
Loading
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'OpnForm',
metaDescription: 'Create beautiful forms for free. Unlimited fields, unlimited submissions. It\'s free and it takes less than 1 minute to create your first form.',
layout: null,
defaultLayout: 'default',
announcement: false,
@ -82,27 +87,7 @@ export default {
confirmationCancel: null
}
}),
metaInfo () {
const { appName } = window.config
const description = "Create beautiful forms for free. Unlimited fields, unlimited submissions. It's free and it takes less than 1 minute to create your first form."
return {
title: appName,
titleTemplate: `%s · ${appName}`,
meta: [
{ vmid: 'description', name: 'description', content: description },
{ vmid: 'og:title', property: 'og:title', content: appName },
{ vmid: 'og:description', property: 'og:description', content: description },
{ vmid: 'og:image', property: 'og:image', content: this.asset('img/social-preview.jpg') },
{ vmid: 'twitter:title', property: 'twitter:title', content: appName },
{ vmid: 'twitter:description', property: 'twitter:description', content: description },
{ vmid: 'twitter:image', property: 'twitter:image', content: this.asset('img/social-preview.jpg') },
{ vmid: 'twitter:card', property: 'twitter:card', content: 'summary_large_image' }
]
}
},
mounted () {
this.$loading = this.$refs.loading
},

22
resources/js/mixins/seo-meta.js vendored Normal file
View File

@ -0,0 +1,22 @@
export default {
metaInfo () {
const title = this.metaTitle ?? 'OpnForm'
const description = this.metaDescription ?? "Create beautiful forms for free. Unlimited fields, unlimited submissions. It's free and it takes less than 1 minute to create your first form."
const image = this.metaImage ?? this.asset('img/social-preview.jpg')
return {
title: title,
titleTemplate: '%s · OpnForm',
meta: [
...(this.metaTags ?? []),
{ vmid: 'og:title', property: 'og:title', content: title },
{ vmid: 'twitter:title', property: 'twitter:title', content: title },
{ vmid: 'description', name: 'description', content: description },
{ vmid: 'og:description', property: 'og:description', content: description },
{ vmid: 'twitter:description', property: 'twitter:description', content: description },
{ vmid: 'twitter:image', property: 'twitter:image', content: image },
{ vmid: 'og:image', property: 'og:image', content: image }
]
}
}
}

View File

@ -59,6 +59,7 @@
import OpenFormFooter from '../../components/pages/OpenFormFooter'
import Testimonials from '../../components/pages/welcome/Testimonials'
import LoginForm from './components/LoginForm'
import SeoMeta from '../../mixins/seo-meta'
export default {
components: {
@ -69,12 +70,10 @@ export default {
middleware: 'guest',
metaInfo () {
return { title: this.$t('login') }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Login',
}),
methods: {

View File

@ -25,17 +25,18 @@
<script>
import Form from 'vform'
import OpenFormFooter from '../../../components/pages/OpenFormFooter'
import SeoMeta from '../../../mixins/seo-meta'
export default {
middleware: 'guest',
components: {
OpenFormFooter
},
metaInfo () {
return { title: this.$t('reset_password') }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Reset Password',
status: '',
form: new Form({
email: ''

View File

@ -35,17 +35,18 @@
<script>
import Form from 'vform'
import OpenFormFooter from '../../../components/pages/OpenFormFooter'
import SeoMeta from '../../../mixins/seo-meta'
export default {
middleware: 'guest',
components: {
OpenFormFooter
},
metaInfo () {
return { title: this.$t('reset_password') }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Reset Password',
status: '',
form: new Form({
token: '',

View File

@ -59,6 +59,7 @@
import OpenFormFooter from '../../components/pages/OpenFormFooter'
import Testimonials from '../../components/pages/welcome/Testimonials'
import RegisterForm from './components/RegisterForm'
import SeoMeta from '../../mixins/seo-meta'
export default {
components: {
@ -69,12 +70,10 @@ export default {
middleware: 'guest',
metaInfo () {
return { title: this.$t('register') }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Register',
}),
computed: {

View File

@ -25,15 +25,14 @@
<script>
import Form from 'vform'
import SeoMeta from '../../../mixins/seo-meta'
export default {
middleware: 'guest',
metaInfo () {
return { title: this.$t('verify_email') }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Verify Email',
status: '',
form: new Form({
email: ''

View File

@ -28,6 +28,7 @@
<script>
import axios from 'axios'
import SeoMeta from '../../../mixins/seo-meta'
const qs = (params) => Object.keys(params).map(key => `${key}=${params[key]}`).join('&')
@ -47,12 +48,10 @@ export default {
},
middleware: 'guest',
metaInfo () {
return { title: this.$t('verify_email') }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Verify Email',
error: '',
success: ''
})

View File

@ -29,6 +29,7 @@ import Form from 'vform'
import {mapState, mapActions} from 'vuex'
import QuickRegister from '../auth/components/QuickRegister'
import initForm from "../../mixins/form_editor/initForm"
import SeoMeta from '../../mixins/seo-meta'
const loadTemplates = function () {
store.commit('open/templates/startLoading')
@ -39,17 +40,13 @@ const loadTemplates = function () {
export default {
name: 'CreateFormGuest',
mixins: [initForm],
mixins: [initForm, SeoMeta],
components: {
QuickRegister
},
middleware: 'guest',
metaInfo() {
return {title: 'Create a new Form as Guest'}
},
beforeRouteEnter(to, from, next) {
loadTemplates()
next()
@ -57,6 +54,7 @@ export default {
data() {
return {
metaTitle: 'Create a new Form as Guest',
stateReady: false,
loading: false,
error: '',

View File

@ -22,6 +22,7 @@ import store from '~/store'
import Form from 'vform'
import {mapState, mapActions} from 'vuex'
import initForm from "../../mixins/form_editor/initForm";
import SeoMeta from '../../mixins/seo-meta'
const loadTemplates = function () {
store.commit('open/templates/startLoading')
@ -33,13 +34,9 @@ const loadTemplates = function () {
export default {
name: 'CreateForm',
mixins: [initForm],
mixins: [initForm, SeoMeta],
components: {},
metaInfo() {
return {title: 'Create a new Form'}
},
beforeRouteEnter(to, from, next) {
loadTemplates()
next()
@ -49,6 +46,7 @@ export default {
data() {
return {
metaTitle: 'Create a new Form',
stateReady: false,
loading: false,
error: '',

View File

@ -20,10 +20,9 @@
import axios from 'axios'
import store from '~/store'
import Breadcrumb from '../../components/common/Breadcrumb'
import Form from 'vform'
import { mapState } from 'vuex'
import SeoMeta from '../../mixins/seo-meta'
const loadForms = function () {
store.commit('open/forms/startLoading')
@ -43,6 +42,7 @@ export default {
next()
},
middleware: 'auth',
mixins: [SeoMeta],
data () {
return {
@ -70,7 +70,10 @@ export default {
},
pageLoaded () {
return !this.loading && this.updatedForm !== null
}
},
metaTitle () {
return 'Edit ' + (this.form ? this.form.title : 'Your Form')
},
},
watch: {
@ -94,11 +97,7 @@ export default {
this.updatedForm = new Form(this.form)
}
},
metaInfo () {
return { title: 'Edit ' + (this.form ? this.form.title : 'Your Form') }
},
methods: {
/**
* Compute max height of editor

View File

@ -9,23 +9,25 @@
<script>
import FormStats from '../../../components/open/forms/components/FormStats'
import SeoMeta from '../../../mixins/seo-meta'
export default {
components: {FormStats},
props: {
form: { type: Object, required: true }
},
metaInfo() {
return {title: (this.form) ? 'Form Analytics - '+this.form.title : 'Form Analytics'}
},
mixins: [SeoMeta],
data: () => ({
}),
mounted() {},
computed: {},
computed: {
metaTitle() {
return (this.form) ? 'Form Analytics - '+this.form.title : 'Form Analytics'
},
},
methods: {

View File

@ -107,6 +107,7 @@ import {mapGetters, mapState} from 'vuex'
import ProTag from '../../../components/common/ProTag'
import VButton from "../../../components/common/Button";
import ExtraMenu from '../../../components/pages/forms/show/ExtraMenu'
import SeoMeta from '../../../mixins/seo-meta'
const loadForms = function () {
store.commit('open/forms/startLoading')
@ -122,6 +123,7 @@ export default {
ProTag,
ExtraMenu
},
mixins: [SeoMeta],
beforeRouteEnter(to, from, next) {
loadForms()
@ -136,6 +138,7 @@ export default {
data() {
return {
metaTitle: 'Home',
tabsList: [
{
name: 'Submissions',
@ -204,11 +207,7 @@ export default {
this.workingForm = new Form(this.form)
}
},
metaInfo() {
return {title: this.$t('home')}
},
methods: {
openCrisp() {
window.$crisp.push(['do', 'chat:show'])

View File

@ -17,6 +17,7 @@ import ShareLink from '../../../components/pages/forms/show/ShareLink'
import EmbedCode from '../../../components/pages/forms/show/EmbedCode'
import UrlFormPrefill from '../../../components/pages/forms/show/UrlFormPrefill'
import RegenerateFormLink from '../../../components/pages/forms/show/RegenerateFormLink'
import SeoMeta from '../../../mixins/seo-meta'
export default {
components: {
@ -28,17 +29,18 @@ export default {
props: {
form: { type: Object, required: true }
},
metaInfo() {
return {title: (this.form) ? 'Form Share - '+this.form.title : 'Form Share'}
},
mixins: [SeoMeta],
data: () => ({
}),
mounted() {},
computed: {},
computed: {
metaTitle() {
return (this.form) ? 'Form Share - '+this.form.title : 'Form Share'
},
},
methods: {

View File

@ -6,23 +6,25 @@
<script>
import FormSubmissions from '../../../components/open/forms/components/FormSubmissions'
import SeoMeta from '../../../mixins/seo-meta'
export default {
components: {FormSubmissions},
props: {
form: { type: Object, required: true }
},
metaInfo() {
return {title: (this.form) ? 'Form Submissions - '+this.form.title : 'Form Submissions'}
},
mixins: [SeoMeta],
data: () => ({
}),
mounted() {},
computed: {},
computed: {
metaTitle() {
return (this.form) ? 'Form Submissions - '+this.form.title : 'Form Submissions'
},
},
methods: {

View File

@ -14,16 +14,15 @@
<script>
import OpenFormFooter from '../../components/pages/OpenFormFooter'
import SeoMeta from '../../mixins/seo-meta'
export default {
components: { OpenFormFooter},
layout: 'default',
metaInfo () {
return { title: 'Privacy Policy' }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Privacy Policy',
}),
computed: {},

View File

@ -14,16 +14,15 @@
<script>
import OpenFormFooter from '../../components/pages/OpenFormFooter'
import SeoMeta from '../../mixins/seo-meta'
export default {
components: { OpenFormFooter },
layout: 'default',
metaInfo () {
return { title: 'Terms & Conditions' }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Terms & Conditions',
}),
computed: {},

View File

@ -18,15 +18,14 @@
<script>
import Form from 'vform'
import axios from 'axios'
import SeoMeta from '../../mixins/seo-meta'
export default {
scrollToTop: false,
metaInfo () {
return { title: 'Account' }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Account',
form: new Form({
identifier: ''
}),

View File

@ -37,17 +37,16 @@
<script>
import Form from 'vform'
import axios from 'axios'
import SeoMeta from '../../mixins/seo-meta'
export default {
components: { },
middleware: 'admin',
scrollToTop: false,
metaInfo () {
return { title: 'Admin' }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Admin',
form: new Form({
identifier: ''
}),

View File

@ -17,16 +17,15 @@
<script>
import axios from 'axios'
import VButton from '../../components/common/Button'
import SeoMeta from '../../mixins/seo-meta'
export default {
components: { VButton },
scrollToTop: false,
metaInfo () {
return { title: 'Billing' }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Billing',
billingLoading: false
}),

View File

@ -24,15 +24,14 @@
<script>
import Form from 'vform'
import SeoMeta from '../../mixins/seo-meta'
export default {
scrollToTop: false,
metaInfo () {
return { title: this.$t('settings') }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Password',
form: new Form({
password: '',
password_confirmation: ''

View File

@ -21,15 +21,14 @@
<script>
import Form from 'vform'
import { mapGetters } from 'vuex'
import SeoMeta from '../../mixins/seo-meta'
export default {
scrollToTop: false,
metaInfo () {
return { title: this.$t('settings') }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Profile',
form: new Form({
name: '',
email: ''

View File

@ -75,17 +75,15 @@
<script>
import Form from 'vform'
import {mapActions, mapState} from 'vuex'
import SeoMeta from '../../mixins/seo-meta'
export default {
components: {},
scrollToTop: false,
metaInfo() {
return {title: 'Workspaces'}
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Workspaces',
form: new Form({
name: '',
emoji: ''

View File

@ -2,17 +2,17 @@
<script>
import { mapGetters } from 'vuex'
import SeoMeta from '../../mixins/seo-meta'
export default {
components: { },
layout: 'default',
middleware: 'auth',
mixins: [SeoMeta],
metaInfo () {
return { title: 'Error' }
},
data: () => ({}),
data: () => ({
metaTitle: 'Error',
}),
mounted () {
this.$router.push({ name: 'pricing' })

View File

@ -18,17 +18,16 @@
<script>
import { mapGetters } from 'vuex'
import OpenFormFooter from '../../components/pages/OpenFormFooter'
import SeoMeta from '../../mixins/seo-meta'
export default {
components: { OpenFormFooter },
layout: 'default',
middleware: 'auth',
metaInfo () {
return { title: 'Subscription Success' }
},
mixins: [SeoMeta],
data: () => ({
metaTitle: 'Subscription Success',
interval: null
}),

View File

@ -108,18 +108,18 @@ import Features from '~/components/pages/welcome/Features'
import MoreFeatures from '~/components/pages/welcome/MoreFeatures'
import OpenFormFooter from '../components/pages/OpenFormFooter'
import Testimonials from '../components/pages/welcome/Testimonials'
import SeoMeta from '../mixins/seo-meta'
export default {
components: {Testimonials, OpenFormFooter, Features, MoreFeatures},
layout: 'default',
metaInfo() {
return {title: 'Create beautiful & open-source forms for free'}
},
mixins: [SeoMeta],
data: () => ({
title: window.config.appName
title: window.config.appName,
metaTitle: 'Create beautiful & open-source forms for free',
}),
mounted() {