Closed umeshgopoint closed 4 years ago
@umeshgopoint Code is fine, Make sure you've added @nuxtjs/amp
as a module in nuxt.config.js
@umeshgopoint Code is fine, Make sure you've added
@nuxtjs/amp
as a module innuxt.config.js
Hi @farnabaz , I have integrated @nuxtjs/amp
as a module in nuxt.config.js
as given instruction. Here is my nuxt.config.js file settings. Please have a look.
import pkg from "./package"
require( "dotenv" ).config()
const axios = require( "axios" )
import redirects from "./assets/redirection-prohbtd-com-september-17-2019.json"
export default {
mode: "universal",
env: {
API_URL: process.env.API_URL || "https://locahost:3000"
},
/*
** Headers of the page
*/
head: {
meta: [
{ charset: "utf-8" },
{
name: "viewport",
content: "width=device-width, initial-scale=1"
}
],
link: [ { rel: "icon", type: "image/x-icon", href: "/favicon.png" } ]
},
/*
** Customize the progress-bar color
** See: https://nuxtjs.org/api/configuration-loading#use-a-custom-loading-component
*/
loading: {
color: "#bfa87c",
height: "4px"
},
sitemap: {
routes() {
return axios
.get( `${process.env.API_URL}/wp-json/phbtd/routes` )
.then( res => {
return res.data
} )
}
},
/*
** Global CSS
*/
css: [
"~/styles/base.scss",
"~/styles/transitions.scss",
"~/styles/fonts.css"
],
/*
** Plugins to load before mounting the App
*/
plugins: [
{ src: "~/plugins/global-component-loader.js" },
{ src: "~/plugins/global-directive-loader.js" },
{ src: "~/plugins/global-svg-loader.js" },
{ src: "~/plugins/wp-shopify.js", mode: "client" },
{ src: "~/plugins/web-font-loader.client.js", mode: "client" },
{ src: "~/plugins/google-gtag.client.js", mode: "client" },
{ src: "~/plugins/jivo-chat.client.js", mode: "client" }
],
/*
** Configure polyfills
** See: https://github.com/Timkor/nuxt-polyfill
*/
polyfill: {
features: [
{
require: "intersection-observer",
detect: () => "IntersectionObserver" in window
}
]
},
/*
** Nuxt.js modules
*/
modules: [
"@nuxtjs/axios",
"@nuxtjs/style-resources",
"nuxt-basic-auth-module",
"nuxt-polyfill",
"@nuxtjs/device",
"@nuxtjs/redirect-module",
"@nuxtjs/sitemap",
"@nuxtjs/dotenv",
[
"nuxt-vuex-localstorage",
{
localStorage: [ "shopify", "persisted" ],
mode: "debug"
}
],
'@nuxtjs/amp'
],
/*
** Define redirects here
*/
redirect: {
rules: () => {
let allRules = redirects.redirects.map( obj => {
// Get the :to url in a safe way
let to = "/"
if ( obj.action_data.url_from ) {
to = obj.action_data.url_from.replace(
"https://locahost:3000",
"/"
)
}
// Return a rule object formatted for @nuxtjs/redirect-module
// Uses regex
return {
from: `^${obj.url}$`,
to: to,
statusCode: 302 //obj.action_code
}
} )
// Add WordPress admin redirect
allRules.push( {
from: "^/wp-admin",
to: `${process.env.API_URL}/wp-admin`,
statusCode: 302
} )
return allRules
}
},
/*
** Load scss globally via styleResources
*/
styleResources: {
scss: [ "~/styles/vars.scss" ]
},
/*
** Axios options. Used for API queries
** See: https://axios.nuxtjs.org/
*/
axios: {
baseURL: process.env.API_URL
},
/*
** Customize router
*/
router: {
linkExactActiveClass: "exact-active-link",
linkActiveClass: "active-link"
},
/*
** Build configuration
*/
build: {
// This and the transpile code below fix an issue with the spread operator in Safari 10.
babel: {
plugins: [ "transform-object-rest-spread" ]
},
transpile: [ "ky" ],
extend( config, ctx ) {
// This is used by plugins/global-svg-loader.js
config.module.noParse = /\/assets\/svgs\/.+(svg$)/
// Includes the Compiler version of Vue.
// If you don't use the <wp-content> component, then you can delete this safely.
config.resolve.alias["vue$"] = "vue/dist/vue.esm.js"
// This stops a @nuxtjs/dotenv error.
config.node = { fs: "empty" }
}
},
/*
** Basic (htaccess) authentication configuration
*/
basic: {
name: "funkhaus",
pass: "funkhaus",
enabled: process.env.BASIC_AUTH_ENABLED === "true"
},
/*
** Server middleware modules
*/
serverMiddleware: [
"redirect-ssl" // Force SSL on all URLs
]
}
Actaull, I want to know how to call the AMP inside the component form the page, Here is my component vue code
import _clamp from "lodash/clamp"
import _get from "lodash/get"
import Vue from "vue"
export default {
amp: 'only',
ampLayout: 'default',
props: {
object: {
type: Object,
default: () => ({})
},
html: String,
src: String,
height: [String, Number],
width: [String, Number],
aspect: [String, Number],
videoSrc: [String, Boolean],
size: {
type: String,
default: "full"
},
color: {
type: String,
default: ""
},
respectMax: {
type: Boolean,
default: false
},
fillSpace: {
type: Boolean,
default: false
},
fit: {
type: String,
default: "cover"
},
poster: {
type: [String, Boolean],
default: ""
},
volume: {
type: Number,
default: 0
},
loop: {
type: Boolean,
default: true
},
progressHandler: {
type: Function,
required: false,
default: () => {}
},
useTransition: {
type: Boolean,
required: false,
default: false
}
},
data() {
return {
loading: true,
imageWidth: 0,
imageHeight: 0,
inView: false,
observerImgSettings: {
callback: this.setImgSrc,
intersection: {
rootMargin: "150px 0px 150px 0px",
threshold: 0
}
},
observerVideoSettings: {
callback: this.setVideoSrc,
intersection: {
rootMargin: "150px 150px 150px 150px",
threshold: 0
}
}
}
},
computed: {
aspectPadding() {
// default to defined aspect, or calculate
const calculatedAspect =
(this.parsedHeight / this.parsedWidth) * 100
return this.aspect || calculatedAspect || 56.25
},
classes() {
return [
"rsp-image-module",
"responsive-image",
`fit-${this.fit}`,
{ loading: this.loading },
{ "fill-space": this.fillSpace },
{ "has-video": this.parsedVideoSrc },
{ "in-view": this.inView }
]
},
imageTag() {
// TODO: Add other img attributes
if (this.$isAMP) {
console.log("AMP is working")
}else {
console.log("AMP is Not working")
}
const fallback = `<img data-umesh="Chandra" src="${this.parsedSrc}" alt="${this.parsedAlt}">`
if (this.html) return this.html
let html = fallback
// Make src and srcset data attributes
html = html.replace("src=", "data-src=")
html = html.replace("srcset=", "data-srcset=")
return html
},
innerHtml() {
return this.imageTag || ""
},
isAcf() {
// check to see if this is an ACF-serialized object
// search for the existence of keys that ACF objects have but Rest-Easy ones don't
return (
this.object.hasOwnProperty("filesize") &&
this.object.hasOwnProperty("mime_type") &&
this.object.hasOwnProperty("modified")
)
},
outerStyles() {
const styles = {}
// set max dims if needed
if (this["respect-max"]) {
styles["max-width"] = `${this.parsedWidth}px`
styles["max-height"] = `${this.parsedHeight}px`
}
// add color bg if needed
if (
this.parsedColor &&
this.parsedColor !== "transparent" &&
this.loading
) {
// set color or SVG background depending on settings
if (this.fit == "cover")
styles["background-color"] = this.parsedColor
else styles["background-image"] = `url("${this.svgBG}")`
// set fit
styles["background-size"] = this.fit
}
return styles
},
parsedAlt() {
return _get(this, "object.alt", "")
},
parsedColor() {
return (
this.color ||
_get(this.object, "primary_color") ||
"transparent"
)
},
parsedFocus() {
return _get(this, "object.focus", { x: 50, y: 50 })
},
parsedHeight() {
// default to defined height
if (this.height) return parseInt(this.height)
return this.imageHeight
},
parsedPoster() {
if (this.poster === null) return ""
return this.poster && this.poster.length
? this.poster
: this.parsedSrc
},
parsedSrc() {
// return hardcoded source if we have one
if (this.src) return this.src
// return ACF source if we have one (only respects fullscreen)
if (this.isAcf) {
return _get(this, "object.sizes.fullscreen", "")
}
return _get(this.targetSize, `url`)
},
parsedVideoSrc() {
const metaString =
_get(this.object, "meta.custom_video_url") ||
_get(this.object, "alt", "")
if (this.videoSrc || this.videoSrc === null) return this.videoSrc
else return String(metaString).includes(".mp4") ? metaString : ""
},
parsedWidth() {
// default to defined width
if (this.width) return parseInt(this.width)
return this.imageWidth
},
sizerStyles() {
if (!this.fillSpace) {
return {
paddingBottom: `${this.aspectPadding}%`
}
}
return {}
},
svgBG() {
if (!this.parsedColor || this.parsedColor == "transparent")
return ""
return `data:image/svg+xml;utf8,
<svg xmlns='http://www.w3.org/2000/svg' xmlns:xlink='http://www.w3.org/1999/xlink'
x='0px' y='0px' viewBox='0 0 ${this.imageWidth} ${this.imageHeight}' xml:space='preserve'>
<rect fill='${this.parsedColor}' width='${this.imageWidth}' height='${this.imageHeight}' />
</svg>`.replace(/\r?\n|\r/g, "")
},
targetSize() {
// should return an object with { height, html, url, width }
// return ACF sizes
if (this.isAcf) {
return {
width: _get(this, "object.sizes.fullscreen-width", 0),
height: _get(this, "object.sizes.fullscreen-height", 0),
url: _get(this, "object.sizes.fullscreen", "")
}
}
// get sizes from image object
const sizes = _get(this.object, `sizes`, {})
// get specified size, or first available size
return (
_get(sizes, this.size) || sizes[_get(Object.keys(sizes), "[0]")]
)
},
transitionKey() {
if (this.useTransition) return this.parsedVideoSrc
else return false
}
},
watch: {
object() {
this.setObjectDimensions()
},
innerHtml() {
this.setMediaClass()
this.setFocalPoint()
},
volume() {
this.setVolume()
}
},
async mounted() {
// ignore if our src is undefined
if (!this.parsedSrc) return
// const img = new Image()
// img.src = this.parsedSrc
// // image was already in cache,
// // set loading var immediately
// if (img.complete) this.loading = false
// // set up height/width if we have an object
this.setObjectDimensions()
// wait for image to load...
this.setMediaClass()
this.setVolume()
// make sure the wrapped image is rendered
await Vue.nextTick()
// set focal point
this.setFocalPoint()
// Check if there's a video progress handler Function
// If there is pass it the current video details every 100ms
// If there is but there's no video, pass it false once
const video = this.$refs.video
if (this.progressHandler) {
if (video)
this.progressInterval = setInterval(() => {
this.progressHandler({
currentTime: video.currentTime,
duration: video.duration,
percentComplete: video.currentTime / video.duration
})
}, 100)
else this.progressHandler(false)
}
},
destroyed() {
if (this.progressInterval) clearInterval(this.progressInterval)
},
methods: {
setImgSrc(isVisible, entry) {
// Add in view class once
if (isVisible) {
this.inView = isVisible
}
if (this.$refs.imageWrap && isVisible && this.loading) {
let lazyImage = this.$refs.imageWrap.querySelector("img")
if (lazyImage.dataset.srcset) {
lazyImage.srcset = lazyImage.dataset.srcset
}
if (lazyImage.dataset.src) {
lazyImage.src = lazyImage.dataset.src
}
this.loading = false
}
},
setVideoSrc(isVisible, entry) {
// Add in view class once
if (isVisible) {
this.inView = isVisible
}
if (this.$refs.video && isVisible && this.loading) {
const lazyVideo = this.$refs.video
if (lazyVideo.dataset.poster) {
lazyVideo.poster = lazyVideo.dataset.poster
}
if (lazyVideo.dataset.src) {
lazyVideo.src = lazyVideo.dataset.src
}
this.loading = false
}
},
setFocalPoint() {
// find the wrapped image
if (
this.$refs.imageWrap &&
this.$refs.imageWrap.querySelector("*")
) {
const wrapped = this.$refs.imageWrap.querySelector("*")
// set its position (default: 50% 50%)
wrapped.style.objectPosition = `${this.parsedFocus.x}% ${this.parsedFocus.y}%`
}
},
setMediaClass() {
// give the "media" class to whatever we are rendering (img or video)
if (!this.$el || !this.$el.querySelector) return
Vue.nextTick(() => {
const media = this.$el.querySelector(".image-sizer > *")
if (media) media.classList.add("media")
})
},
setObjectDimensions() {
if (this.object) {
this.imageWidth = _get(this.targetSize, `width`)
this.imageHeight = _get(this.targetSize, `height`)
}
},
async setVolume() {
await Vue.nextTick()
const video = this.$el.querySelector("video")
if (video) {
video.volume = _clamp(this.volume, 0, 1)
}
}
}
}
Please check and let me know can we call AMP directly in Component Vue.
Awaiting for your kind response. Actually I am a beginner in NUXT.
Is this content of your page? or it's just a standalone component outside of the pages
directory?
amp: 'only'
and ampLayout: 'default'
are only valid in pages (files inside pages
directory)
Hi, I have installed this module and while using this $isAMP check-in component section then its not working. Here is my code :
Full Code--