SEO meta nuxt migration (#274)
* SEO meta nuxt migration * Polish seo metas, add defaults for OG and twitter --------- Co-authored-by: Julien Nahum <julien@nahum.net>
This commit is contained in:
parent
9594157a2d
commit
f87e3f1685
|
@ -44,6 +44,17 @@ export default {
|
|||
components: {},
|
||||
|
||||
setup() {
|
||||
useOpnSeoMeta({
|
||||
title: 'OpnForm',
|
||||
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.',
|
||||
ogImage: '/img/social-preview.jpg',
|
||||
})
|
||||
useHead({
|
||||
titleTemplate: (titleChunk) => {
|
||||
return titleChunk ? `${titleChunk} - OpnForm` : 'OpnForm';
|
||||
}
|
||||
})
|
||||
|
||||
const appStore = useAppStore()
|
||||
|
||||
return {
|
||||
|
@ -57,8 +68,6 @@ export default {
|
|||
},
|
||||
|
||||
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.',
|
||||
announcement: false,
|
||||
alert: {
|
||||
type: null,
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
export const useOpnSeoMeta = (meta) => {
|
||||
return useSeoMeta({
|
||||
...meta.title ? {
|
||||
ogTitle: meta.title,
|
||||
twitterTitle: meta.title,
|
||||
} : {},
|
||||
...meta.description ? {
|
||||
ogDescription: meta.description,
|
||||
twitterDescription: meta.description,
|
||||
} : {},
|
||||
...meta.ogImage ? {
|
||||
twitterImage: meta.ogImage,
|
||||
} : {},
|
||||
...meta,
|
||||
})
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
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')
|
||||
const metaTemplate = this.metaTemplate ?? '%s · OpnForm'
|
||||
|
||||
return {
|
||||
title: title,
|
||||
titleTemplate: metaTemplate,
|
||||
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 }
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -496,13 +496,16 @@
|
|||
<script>
|
||||
import { computed } from 'vue'
|
||||
import { useAuthStore } from '../stores/auth'
|
||||
import SeoMeta from '../mixins/seo-meta.js'
|
||||
|
||||
export default {
|
||||
layout: 'default',
|
||||
mixins: [SeoMeta],
|
||||
|
||||
setup () {
|
||||
useOpnSeoMeta({
|
||||
title: 'Free AI form builder',
|
||||
description: 'Transform your ideas into fully functional forms with OpnForm AI Builder – quick, accurate, and tailored to fit any requirement.'
|
||||
})
|
||||
|
||||
const authStore = useAuthStore()
|
||||
defineRouteRules({
|
||||
prerender: true
|
||||
|
@ -514,8 +517,6 @@ export default {
|
|||
},
|
||||
|
||||
data: () => ({
|
||||
title: 'OpnForm',
|
||||
metaTitle: 'AI form builder for free',
|
||||
}),
|
||||
|
||||
mounted() {},
|
||||
|
|
|
@ -26,8 +26,13 @@
|
|||
export default {
|
||||
middleware: 'guest',
|
||||
|
||||
setup () {
|
||||
useOpnSeoMeta({
|
||||
title: 'Reset Password'
|
||||
})
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
metaTitle: 'Reset Password',
|
||||
status: '',
|
||||
form: useForm({
|
||||
email: ''
|
||||
|
|
|
@ -36,8 +36,13 @@
|
|||
export default {
|
||||
middleware: 'guest',
|
||||
|
||||
setup () {
|
||||
useOpnSeoMeta({
|
||||
title: 'Reset Password'
|
||||
})
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
metaTitle: 'Reset Password',
|
||||
status: '',
|
||||
form: useForm({
|
||||
token: '',
|
||||
|
|
|
@ -52,6 +52,10 @@ export default {
|
|||
}
|
||||
})
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: 'Edit ' + ((form && form.value) ? form.value.title : 'Your Form')
|
||||
})
|
||||
|
||||
return {
|
||||
formsStore,
|
||||
workingFormStore,
|
||||
|
@ -70,9 +74,6 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
metaTitle () {
|
||||
return 'Edit ' + (this.form ? this.form.title : 'Your Form')
|
||||
}
|
||||
},
|
||||
|
||||
async beforeMount() {
|
||||
|
|
|
@ -113,32 +113,36 @@ onMounted(() => {
|
|||
|
||||
await loadForm(slug)
|
||||
|
||||
// metaTitle () {
|
||||
// if (this.form && this.form.is_pro && this.form.seo_meta.page_title) {
|
||||
// return this.form.seo_meta.page_title
|
||||
// }
|
||||
// return this.form ? this.form.title : 'Create beautiful forms'
|
||||
// },
|
||||
// metaTemplate () {
|
||||
// if (this.form && this.form.is_pro && this.form.seo_meta.page_title) {
|
||||
// // Disable template if custom SEO title
|
||||
// return '%s'
|
||||
// }
|
||||
// return null
|
||||
// },
|
||||
// metaDescription () {
|
||||
// if (this.form && this.form.is_pro && this.form.seo_meta.page_description) {
|
||||
// return this.form.seo_meta.page_description
|
||||
// }
|
||||
// return (this.form && this.form.description) ? this.form.description.substring(0, 160) : null
|
||||
// },
|
||||
// metaImage () {
|
||||
// if (this.form && this.form.is_pro && this.form.seo_meta.page_thumbnail) {
|
||||
// return this.form.seo_meta.page_thumbnail
|
||||
// }
|
||||
// return (this.form && this.form.cover_picture) ? this.form.cover_picture : null
|
||||
// },
|
||||
// metaTags () {
|
||||
// return (this.form && this.form.can_be_indexed) ? [] : [{ name: 'robots', content: 'noindex' }]
|
||||
// }
|
||||
useOpnSeoMeta({
|
||||
title: () => {
|
||||
if (form && form.value.is_pro && form.value.seo_meta.page_title) {
|
||||
return form.value.seo_meta.page_title
|
||||
}
|
||||
return form.value ? form.value.title : 'Create beautiful forms'
|
||||
},
|
||||
description () {
|
||||
if (form && form.value.is_pro && form.value.seo_meta.page_description) {
|
||||
return form.value.seo_meta.page_description
|
||||
}
|
||||
return (form && form.value.description) ? form.value.description.substring(0, 160) : null
|
||||
},
|
||||
ogImage () {
|
||||
if (form && form.value.is_pro && form.value.seo_meta.page_thumbnail) {
|
||||
return form.value.seo_meta.page_thumbnail
|
||||
}
|
||||
return (form && form.value.cover_picture) ? form.value.cover_picture : null
|
||||
},
|
||||
robots () {
|
||||
return (form && form.value.can_be_indexed) ? null : 'noindex, nofollow'
|
||||
}
|
||||
})
|
||||
useHead({
|
||||
titleTemplate: (titleChunk) => {
|
||||
if (form && form.value.is_pro && form.value.seo_meta.page_title) {
|
||||
// Disable template if custom SEO title
|
||||
return titleChunk
|
||||
}
|
||||
return titleChunk ? `${titleChunk} - OpnForm` : 'OpnForm';
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -144,6 +144,10 @@ export default {
|
|||
middleware: 'auth',
|
||||
|
||||
setup () {
|
||||
useOpnSeoMeta({
|
||||
title: 'Home'
|
||||
})
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const formsStore = useFormsStore()
|
||||
const workingFormStore = useWorkingFormStore()
|
||||
|
@ -167,7 +171,6 @@ export default {
|
|||
|
||||
data () {
|
||||
return {
|
||||
metaTitle: 'Home',
|
||||
tabsList: [
|
||||
{
|
||||
name: 'Submissions',
|
||||
|
|
|
@ -26,7 +26,6 @@ import EmbedCode from '../../../../components/pages/forms/show/EmbedCode.vue'
|
|||
import FormQrCode from '../../../../components/pages/forms/show/FormQrCode.vue'
|
||||
import UrlFormPrefill from '../../../../components/pages/forms/show/UrlFormPrefill.vue'
|
||||
import RegenerateFormLink from '../../../../components/pages/forms/show/RegenerateFormLink.vue'
|
||||
import SeoMeta from '../../../../mixins/seo-meta.js'
|
||||
import AdvancedFormUrlSettings from '../../../../components/open/forms/components/AdvancedFormUrlSettings.vue'
|
||||
import EmbedFormAsPopupModal from '../../../../components/pages/forms/show/EmbedFormAsPopupModal.vue'
|
||||
|
||||
|
@ -45,6 +44,12 @@ export default {
|
|||
form: {type: Object, required: true},
|
||||
},
|
||||
|
||||
setup (props) {
|
||||
useOpnSeoMeta({
|
||||
title: (props.form) ? 'Share Form - '+props.form.title : 'Share Form'
|
||||
})
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
shareFormConfig: {
|
||||
hide_title: false,
|
||||
|
@ -53,9 +58,6 @@ export default {
|
|||
}),
|
||||
|
||||
computed: {
|
||||
metaTitle() {
|
||||
return (this.form) ? 'Form Share - '+this.form.title : 'Form Share'
|
||||
},
|
||||
shareUrlForQueryParams () {
|
||||
let queryStr = ''
|
||||
for (const [key, value] of Object.entries(this.shareFormConfig)) {
|
||||
|
|
|
@ -9,7 +9,6 @@
|
|||
|
||||
<script>
|
||||
import FormStats from '../../../../components/open/forms/components/FormStats.vue'
|
||||
import SeoMeta from '../../../../mixins/seo-meta.js'
|
||||
|
||||
export default {
|
||||
components: {FormStats},
|
||||
|
@ -18,10 +17,13 @@ export default {
|
|||
form: {type: Object, required: true},
|
||||
},
|
||||
|
||||
setup (props) {
|
||||
useOpnSeoMeta({
|
||||
title: (props.form) ? 'Form Analytics - '+props.form.title : 'Form Analytics'
|
||||
})
|
||||
},
|
||||
|
||||
computed: {
|
||||
metaTitle() {
|
||||
return (this.form ? ('Form Analytics - ' + this.form.title) : 'Form Analytics')
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
|
|
@ -6,14 +6,18 @@
|
|||
|
||||
<script>
|
||||
import FormSubmissions from '../../../../components/open/forms/components/FormSubmissions.vue'
|
||||
import SeoMeta from '../../../../mixins/seo-meta.js'
|
||||
|
||||
export default {
|
||||
components: {FormSubmissions},
|
||||
props: {
|
||||
form: {type: Object, required: true}
|
||||
},
|
||||
mixins: [SeoMeta],
|
||||
|
||||
setup (props) {
|
||||
useOpnSeoMeta({
|
||||
title: (props.form) ? 'Form Submissions - '+props.form.title : 'Form Submissions'
|
||||
})
|
||||
},
|
||||
|
||||
data: () => ({}),
|
||||
|
||||
|
@ -21,9 +25,6 @@ export default {
|
|||
},
|
||||
|
||||
computed: {
|
||||
metaTitle() {
|
||||
return (this.form) ? 'Form Submissions - ' + this.form.title : 'Form Submissions'
|
||||
},
|
||||
},
|
||||
|
||||
methods: {}
|
||||
|
|
|
@ -48,7 +48,10 @@ const workspace = computed(() => workspacesStore.getCurrent)
|
|||
const workspacesLoading = computed(() => workspacesStore.loading)
|
||||
const form = storeToRefs(workingFormStore).content
|
||||
|
||||
// metaTitle: 'Create a new Form as Guest',
|
||||
useOpnSeoMeta({
|
||||
title: 'Create a new Form for free',
|
||||
})
|
||||
|
||||
// Data
|
||||
const stateReady = ref(false)
|
||||
const loading = ref(false)
|
||||
|
|
|
@ -33,7 +33,9 @@ definePageMeta({
|
|||
middleware: "auth"
|
||||
})
|
||||
|
||||
const metaTitle = 'Create a new Form'
|
||||
useOpnSeoMeta({
|
||||
title: 'Create a new Form'
|
||||
})
|
||||
|
||||
onBeforeRouteLeave((to, from, next) => {
|
||||
if (isDirty()) {
|
||||
|
|
|
@ -125,11 +125,10 @@ definePageMeta({
|
|||
middleware: "auth"
|
||||
})
|
||||
|
||||
// metaTitle: {type: String, default: 'Your Forms'},
|
||||
// metaDescription: {
|
||||
// type: String,
|
||||
// default: 'All of your OpnForm are here. Create new forms, or update your existing one!'
|
||||
// }
|
||||
useOpnSeoMeta({
|
||||
title: 'Your Forms',
|
||||
description: 'All of your OpnForm are here. Create new forms, or update your existing forms.'
|
||||
})
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const formsStore = useFormsStore()
|
||||
|
|
|
@ -191,12 +191,10 @@ import PricingTable from '../components/pages/pricing/PricingTable.vue'
|
|||
import AiFeature from '~/components/pages/welcome/AiFeature.vue'
|
||||
import Testimonials from '../components/pages/welcome/Testimonials.vue'
|
||||
import TemplatesSlider from '../components/pages/welcome/TemplatesSlider.vue'
|
||||
import SeoMeta from '../mixins/seo-meta.js'
|
||||
import opnformConfig from "~/opnform.config.js";
|
||||
|
||||
export default {
|
||||
components: {Testimonials, Features, MoreFeatures, PricingTable, AiFeature, TemplatesSlider},
|
||||
mixins: [SeoMeta],
|
||||
layout: 'default',
|
||||
|
||||
setup() {
|
||||
|
@ -213,8 +211,6 @@ export default {
|
|||
},
|
||||
|
||||
data: () => ({
|
||||
title: 'OpnForm',
|
||||
metaTitle: 'Create beautiful & open-source forms for free'
|
||||
}),
|
||||
|
||||
computed: {
|
||||
|
|
|
@ -52,29 +52,16 @@
|
|||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script setup>
|
||||
import LoginForm from "~/components/pages/auth/components/LoginForm.vue"
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LoginForm
|
||||
},
|
||||
|
||||
setup() {
|
||||
definePageMeta({
|
||||
middleware: "guest"
|
||||
})
|
||||
defineRouteRules({
|
||||
prerender: true
|
||||
})
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
metaTitle: 'Login',
|
||||
}),
|
||||
|
||||
methods: {
|
||||
|
||||
}
|
||||
}
|
||||
definePageMeta({
|
||||
middleware: "guest"
|
||||
})
|
||||
defineRouteRules({
|
||||
prerender: true
|
||||
})
|
||||
useOpnSeoMeta({
|
||||
title: 'Login'
|
||||
})
|
||||
</script>
|
||||
|
|
|
@ -245,6 +245,11 @@ export default {
|
|||
layout: 'default',
|
||||
|
||||
setup () {
|
||||
useOpnSeoMeta({
|
||||
title: 'Pricing',
|
||||
description: 'All of our core features are free, and there is no quantity limit. You can also created more advanced and customized forms with OpnForms Pro.'
|
||||
})
|
||||
|
||||
definePageMeta({
|
||||
middleware: [
|
||||
function (to, from) {
|
||||
|
@ -264,15 +269,6 @@ export default {
|
|||
}
|
||||
},
|
||||
|
||||
data: () => ({
|
||||
metaTitle: 'Pricing',
|
||||
metaDescription: 'All of our core features are free, and there is no quantity limit. You can also created more advanced and customized forms with OpnForms Pro.',
|
||||
}),
|
||||
|
||||
mounted() {},
|
||||
|
||||
computed: {},
|
||||
|
||||
methods: {
|
||||
contactUs() {
|
||||
window.$crisp.push(['do', 'chat:show'])
|
||||
|
|
|
@ -13,12 +13,13 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
|
||||
// metaTitle: 'Privacy Policy',
|
||||
|
||||
import {useNotionPagesStore} from "~/stores/notion_pages.js";
|
||||
import {computed} from "vue";
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: 'Privacy Policy'
|
||||
})
|
||||
|
||||
const notionPageStore = useNotionPagesStore()
|
||||
await notionPageStore.load('9c97349ceda7455aab9b341d1ff70f79')
|
||||
|
||||
|
|
|
@ -64,6 +64,10 @@ export default {
|
|||
},
|
||||
|
||||
setup() {
|
||||
useOpnSeoMeta({
|
||||
title: 'Register'
|
||||
})
|
||||
|
||||
definePageMeta({
|
||||
middleware: "guest"
|
||||
})
|
||||
|
@ -75,7 +79,6 @@ export default {
|
|||
middleware: 'guest',
|
||||
|
||||
data: () => ({
|
||||
metaTitle: 'Register'
|
||||
}),
|
||||
|
||||
computed: {},
|
||||
|
|
|
@ -45,6 +45,10 @@
|
|||
middleware: "auth"
|
||||
})
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: 'Settings'
|
||||
})
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const user = computed(() => authStore.user)
|
||||
const tabsList = computed(() => {
|
||||
|
@ -84,4 +88,3 @@
|
|||
return tabs
|
||||
})
|
||||
</script>
|
||||
|
|
@ -20,9 +20,12 @@ import { useRouter } from 'vue-router';
|
|||
|
||||
const router = useRouter()
|
||||
const authStore = useAuthStore()
|
||||
const metaTitle = 'Account'
|
||||
let loading = false
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: 'Account'
|
||||
})
|
||||
|
||||
const deleteAccount = () => {
|
||||
loading = true
|
||||
opnFetch('/user', {method:'DELETE'}).then(async (data) => {
|
||||
|
|
|
@ -41,7 +41,10 @@ definePageMeta({
|
|||
middleware: "admin"
|
||||
})
|
||||
|
||||
const metaTitle = 'Admin'
|
||||
useOpnSeoMeta({
|
||||
title: 'Admin'
|
||||
})
|
||||
|
||||
const authStore = useAuthStore()
|
||||
const workspacesStore = useWorkspacesStore()
|
||||
const router = useRouter()
|
||||
|
|
|
@ -24,7 +24,10 @@ import { computed } from 'vue'
|
|||
import { useAuthStore } from '../../stores/auth'
|
||||
import AppSumoBilling from '../../components/vendor/appsumo/AppSumoBilling.vue'
|
||||
|
||||
const metaTitle = 'Billing'
|
||||
useOpnSeoMeta({
|
||||
title: 'Billing'
|
||||
})
|
||||
|
||||
const authStore = useAuthStore()
|
||||
let user = computed(() => authStore.user)
|
||||
let billingLoading = false
|
||||
|
|
|
@ -25,7 +25,10 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
const metaTitle = 'Password'
|
||||
useOpnSeoMeta({
|
||||
title: 'Password'
|
||||
})
|
||||
|
||||
let form = useForm({
|
||||
password: '',
|
||||
password_confirmation: ''
|
||||
|
|
|
@ -23,7 +23,11 @@
|
|||
<script setup>
|
||||
const authStore = useAuthStore()
|
||||
const user = computed(() => authStore.user)
|
||||
const metaTitle = 'Profile'
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: 'Profile'
|
||||
})
|
||||
|
||||
let form = useForm({
|
||||
name: '',
|
||||
email: ''
|
||||
|
|
|
@ -122,7 +122,11 @@ const crisp = useCrisp()
|
|||
const workspacesStore = useWorkspacesStore()
|
||||
const workspaces = computed(() => workspacesStore.getAll)
|
||||
let loading = computed(() => workspacesStore.loading)
|
||||
const metaTitle = 'Workspaces'
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: 'Workspaces'
|
||||
})
|
||||
|
||||
let form = useForm({
|
||||
name: '',
|
||||
emoji: ''
|
||||
|
|
|
@ -3,15 +3,17 @@
|
|||
<script>
|
||||
import { computed } from 'vue'
|
||||
import { useAuthStore } from '../../stores/auth'
|
||||
import SeoMeta from '../../mixins/seo-meta.js'
|
||||
|
||||
export default {
|
||||
components: { },
|
||||
layout: 'default',
|
||||
middleware: 'auth',
|
||||
mixins: [SeoMeta],
|
||||
|
||||
setup () {
|
||||
useOpnSeoMeta({
|
||||
title: 'Error'
|
||||
})
|
||||
|
||||
const authStore = useAuthStore()
|
||||
return {
|
||||
authenticated : computed(() => authStore.check),
|
||||
|
@ -19,7 +21,6 @@ export default {
|
|||
},
|
||||
|
||||
data: () => ({
|
||||
metaTitle: 'Error',
|
||||
}),
|
||||
|
||||
mounted () {
|
||||
|
|
|
@ -18,13 +18,16 @@
|
|||
<script>
|
||||
import { computed } from 'vue'
|
||||
import { useAuthStore } from '../../stores/auth'
|
||||
import SeoMeta from '../../mixins/seo-meta.js'
|
||||
|
||||
export default {
|
||||
layout: 'default',
|
||||
middleware: 'auth',
|
||||
|
||||
setup () {
|
||||
useOpnSeoMeta({
|
||||
title: 'Subscription Success'
|
||||
})
|
||||
|
||||
const authStore = useAuthStore()
|
||||
return {
|
||||
authStore,
|
||||
|
@ -34,7 +37,6 @@ export default {
|
|||
},
|
||||
|
||||
data: () => ({
|
||||
metaTitle: 'Subscription Success',
|
||||
interval: null
|
||||
}),
|
||||
|
||||
|
|
|
@ -265,24 +265,24 @@ const copyTemplateUrl = () => {
|
|||
useAlert().success('Copied!')
|
||||
}
|
||||
|
||||
// metaTitle() {
|
||||
// return this.template ? this.template.name : 'Form Template'
|
||||
// },
|
||||
// metaDescription() {
|
||||
// if (!this.template) return null
|
||||
// // take the first 140 characters of the description
|
||||
// return this.template.short_description?.substring(0, 140) + '... | Customize any template and create your own form in minutes.'
|
||||
// },
|
||||
// metaImage() {
|
||||
// if (!this.template) return null
|
||||
// return this.template.image_url
|
||||
// },
|
||||
// metaTags() {
|
||||
// if (!this.template) {
|
||||
// return [];
|
||||
// }
|
||||
// return this.template.publicly_listed ? [] : [{name: 'robots', content: 'noindex'}]
|
||||
// },
|
||||
useOpnSeoMeta({
|
||||
title: () => {
|
||||
return template ? template.value.name : 'Form Template'
|
||||
},
|
||||
description () {
|
||||
if (!template || !template.value) return null
|
||||
// take the first 140 characters of the description
|
||||
return template.value.short_description?.substring(0, 140) + '... | Customize any template and create your own form in minutes.'
|
||||
},
|
||||
ogImage () {
|
||||
if (!template || !template.value) return null
|
||||
return template.value.image_url
|
||||
},
|
||||
robots () {
|
||||
if (!template || !template.value) return null
|
||||
return template.value.publicly_listed ? null : 'noindex'
|
||||
}
|
||||
})
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
|
|
|
@ -26,10 +26,10 @@ defineRouteRules({
|
|||
prerender: true
|
||||
})
|
||||
|
||||
// props: {
|
||||
// metaTitle: { type: String, default: 'Templates' },
|
||||
// metaDescription: { type: String, default: 'Our collection of beautiful templates to create your own forms!' }
|
||||
// },
|
||||
useOpnSeoMeta({
|
||||
title: 'Form Templates',
|
||||
description: 'Our collection of beautiful templates to create your own forms!'
|
||||
})
|
||||
|
||||
const templatesStore = useTemplatesStore()
|
||||
loadAllTemplates(templatesStore)
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
<breadcrumb :path="breadcrumbs"/>
|
||||
|
||||
<p v-if="industry === null || !industry" class="text-center my-4">
|
||||
We could not find this type.
|
||||
We could not find this industry.
|
||||
</p>
|
||||
<template v-else>
|
||||
<section class="py-12 sm:py-16 bg-gray-50 border-b border-gray-200">
|
||||
|
@ -23,7 +23,7 @@
|
|||
</section>
|
||||
|
||||
|
||||
<templates-list :templates="templates" :filter-industries="false" :show-types="false">
|
||||
<templates-list :templates="templates" :filter-industries="false" :show-industrys="false">
|
||||
<template #before-lists>
|
||||
<section class="py-12 bg-white border-t border-gray-200 sm:py-16">
|
||||
<div class="px-4 mx-auto sm:px-6 lg:px-8 max-w-7xl">
|
||||
|
@ -70,6 +70,29 @@ const breadcrumbs = computed(() => {
|
|||
|
||||
const industry = computed(() => templatesStore.industries.get(route.params.slug))
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: () => {
|
||||
if (!industry.value) return 'Form Templates'
|
||||
if (industry.value.meta_title.length > 60) {
|
||||
return industry.value.meta_title
|
||||
}
|
||||
return industry.value.meta_title
|
||||
},
|
||||
description: () => industry.value ? industry.value.meta_description: 'Our collection of beautiful templates to create your own forms!'
|
||||
})
|
||||
useHead({
|
||||
titleTemplate: (titleChunk) => {
|
||||
// Disable title template for longer titles
|
||||
if (industry.value
|
||||
&& industry.value.meta_title.length < 60
|
||||
&& !industry.value.meta_title.toLowerCase().includes('opnform')
|
||||
) {
|
||||
return titleChunk ? `${titleChunk} - OpnForm` : 'Form Templates - OpnForm'
|
||||
}
|
||||
return titleChunk ? titleChunk : 'Form Templates - OpnForm'
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
|
|
|
@ -24,9 +24,11 @@ export default {
|
|||
components: { TemplatesList },
|
||||
middleware: 'auth',
|
||||
|
||||
props: {
|
||||
metaTitle: { type: String, default: 'My Templates' },
|
||||
metaDescription: { type: String, default: 'Our collection of beautiful templates to create your own forms!' }
|
||||
setup () {
|
||||
useOpnSeoMeta({
|
||||
title: 'My Templates',
|
||||
description: 'Our collection of beautiful templates to create your own forms!'
|
||||
})
|
||||
},
|
||||
|
||||
data () {
|
||||
|
|
|
@ -71,6 +71,29 @@ const breadcrumbs = computed(() => {
|
|||
|
||||
const type = computed(() => templatesStore.types.get(route.params.slug))
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: () => {
|
||||
if (!type.value) return 'Form Templates'
|
||||
if (type.value.meta_title.length > 60) {
|
||||
return type.value.meta_title
|
||||
}
|
||||
return type.value.meta_title
|
||||
},
|
||||
description: () => type.value ? type.value.meta_description: 'Our collection of beautiful templates to create your own forms!'
|
||||
})
|
||||
useHead({
|
||||
titleTemplate: (titleChunk) => {
|
||||
// Disable title template for longer titles
|
||||
if (type.value
|
||||
&& type.value.meta_title.length < 60
|
||||
&& !type.value.meta_title.toLowerCase().includes('opnform')
|
||||
) {
|
||||
return titleChunk ? `${titleChunk} - OpnForm` : 'Form Templates - OpnForm'
|
||||
}
|
||||
return titleChunk ? titleChunk : 'Form Templates - OpnForm'
|
||||
}
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
<style lang='scss'>
|
||||
|
|
|
@ -13,11 +13,13 @@
|
|||
</template>
|
||||
|
||||
<script setup>
|
||||
// metaTitle: 'Terms & Conditions',
|
||||
|
||||
import {useNotionPagesStore} from "~/stores/notion_pages.js";
|
||||
import {computed} from "vue";
|
||||
|
||||
useOpnSeoMeta({
|
||||
title: 'Terms & Conditions'
|
||||
})
|
||||
|
||||
const notionPageStore = useNotionPagesStore()
|
||||
await notionPageStore.load('246420da2834480ca04047b0c5a00929')
|
||||
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 15 KiB |
Loading…
Reference in New Issue