Updating Third party capital version. (#54418)
Updated Third-party-capital version. Refactored `next/third-parties` to update the way components are built. Updated tests. cc: @kara @huozhi @gnoff
This commit is contained in:
parent
30937eebc2
commit
d3a107991c
16 changed files with 94 additions and 193 deletions
|
@ -10,13 +10,13 @@
|
||||||
|
|
||||||
### YouTube Embed
|
### YouTube Embed
|
||||||
|
|
||||||
The `YoutubeEmbed` component is used to load and display a YouTube embed. This component loads faster by using [lite-youtube-embed](https://github.com/paulirish/lite-youtube-embed) under the hood.
|
The `YouTubeEmbed` component is used to load and display a YouTube embed. This component loads faster by using [lite-youtube-embed](https://github.com/paulirish/lite-youtube-embed) under the hood.
|
||||||
|
|
||||||
```js
|
```js
|
||||||
import { YoutubeEmbed } from '@next/third-parties/google'
|
import { YouTubeEmbed } from '@next/third-parties/google'
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
return <YoutubeEmbed videoid="ogfYd705cRs" height={400} />
|
return <YouTubeEmbed videoid="ogfYd705cRs" height={400} />
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
@ -33,8 +33,8 @@ export default function Page() {
|
||||||
apiKey="XYZ"
|
apiKey="XYZ"
|
||||||
height={200}
|
height={200}
|
||||||
width="100%"
|
width="100%"
|
||||||
mapMode="place"
|
mode="place"
|
||||||
parameters="q=Brooklyn+Bridge,New+York,NY"
|
q="Brooklyn+Bridge,New+York,NY"
|
||||||
/>
|
/>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,12 +16,11 @@
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"build": "rm -rf dist && tsc -d -p tsconfig.json",
|
"build": "rm -rf dist && tsc -d -p tsconfig.json",
|
||||||
"prepublishOnly": "cd ../../ && turbo run build",
|
"prepublishOnly": "cd ../../ && turbo run build",
|
||||||
"update-third-parties": "rm -rf src/**/index.tsx && node scripts/update-third-parties",
|
|
||||||
"dev": "tsc -d -w -p tsconfig.json",
|
"dev": "tsc -d -w -p tsconfig.json",
|
||||||
"typescript": "tsec --noEmit -p tsconfig.json"
|
"typescript": "tsec --noEmit -p tsconfig.json"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"third-party-capital": "1.0.17"
|
"third-party-capital": "1.0.20"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"next": "13.4.20-canary.12",
|
"next": "13.4.20-canary.12",
|
||||||
|
|
|
@ -1,118 +0,0 @@
|
||||||
const fs = require('fs/promises')
|
|
||||||
const path = require('path')
|
|
||||||
const AllThirdParties = require('third-party-capital')
|
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
||||||
const prettier = require('prettier')
|
|
||||||
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
||||||
const { outdent } = require('outdent')
|
|
||||||
|
|
||||||
const scriptStrategy = {
|
|
||||||
server: 'beforeInteractive',
|
|
||||||
client: 'afterInteractive',
|
|
||||||
idle: 'lazyOnload',
|
|
||||||
worker: 'worker',
|
|
||||||
}
|
|
||||||
|
|
||||||
const SRC = path.join(__dirname, '../src')
|
|
||||||
const CONFIG_FILE_NAME = 'tpc-config.json'
|
|
||||||
|
|
||||||
function generateComponent(thirdParty) {
|
|
||||||
let thirdPartyFunctions = ''
|
|
||||||
|
|
||||||
const insertScripts = (id, scripts, stylesheets) => {
|
|
||||||
let props = ''
|
|
||||||
|
|
||||||
if (stylesheets?.length > 0) {
|
|
||||||
props += `
|
|
||||||
stylesheets={${JSON.stringify(stylesheets)}}`
|
|
||||||
}
|
|
||||||
|
|
||||||
return scripts
|
|
||||||
.map((script) => {
|
|
||||||
if (typeof script === 'string') {
|
|
||||||
// External script with only URL
|
|
||||||
return `<Script src="${script}"${props} />`
|
|
||||||
} else if (script.url) {
|
|
||||||
// External script with additional properties
|
|
||||||
// TODO: Validate the strategy. Set fallback if an inpnpvalid strategy is passed
|
|
||||||
const { url, strategy } = script
|
|
||||||
return `<Script src={\`${url}\`} strategy="${scriptStrategy[strategy]}"${props} />`
|
|
||||||
} else if (script.code) {
|
|
||||||
// Inline script with additional properties
|
|
||||||
const { code, strategy } = script
|
|
||||||
return outdent`<Script
|
|
||||||
id="${id}"
|
|
||||||
strategy="${scriptStrategy[strategy]}"
|
|
||||||
dangerouslySetInnerHTML={{
|
|
||||||
__html: \`${code}\`,
|
|
||||||
}}${props}
|
|
||||||
/>`
|
|
||||||
}
|
|
||||||
|
|
||||||
return ''
|
|
||||||
})
|
|
||||||
.join('')
|
|
||||||
}
|
|
||||||
|
|
||||||
const { id, description, content, scripts, stylesheets } =
|
|
||||||
AllThirdParties[thirdParty]
|
|
||||||
|
|
||||||
thirdPartyFunctions += outdent`
|
|
||||||
|
|
||||||
// ${description}
|
|
||||||
export function ${thirdParty}(args: Types.${thirdParty}) {
|
|
||||||
return (
|
|
||||||
<ThirdPartyScriptEmbed
|
|
||||||
${content ? 'height={args.height || null}' : ''}
|
|
||||||
${content ? 'width={args.width || null}' : ''}
|
|
||||||
${content ? `content={\`${content}\`}` : ''}
|
|
||||||
dataNtpc="${thirdParty}"
|
|
||||||
>
|
|
||||||
${scripts?.length > 0 ? insertScripts(id, scripts, stylesheets) : ''}
|
|
||||||
</ThirdPartyScriptEmbed>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
return thirdPartyFunctions
|
|
||||||
}
|
|
||||||
|
|
||||||
;(async () => {
|
|
||||||
const dirs = (await fs.readdir(SRC, { withFileTypes: true }))
|
|
||||||
.filter((dirent) => dirent.isDirectory())
|
|
||||||
.map((dirent) => dirent.name)
|
|
||||||
|
|
||||||
for (let dir of dirs) {
|
|
||||||
// Fetch the list of third-parties from tpc-config.json
|
|
||||||
// Then retrieve its loading instructions from Third Party Capital
|
|
||||||
const dirPath = path.join(SRC, dir)
|
|
||||||
|
|
||||||
const configFile = (await fs.readdir(dirPath)).find(
|
|
||||||
(file) => file === CONFIG_FILE_NAME
|
|
||||||
)
|
|
||||||
|
|
||||||
if (!configFile) continue
|
|
||||||
|
|
||||||
const config = JSON.parse(await fs.readFile(path.join(dirPath, configFile)))
|
|
||||||
|
|
||||||
let thirdPartyFunctions = `/**
|
|
||||||
* This is an autogenerated file by update-third-parties.js
|
|
||||||
*/
|
|
||||||
import React from 'react'
|
|
||||||
import Script from 'next/script'
|
|
||||||
|
|
||||||
import ThirdPartyScriptEmbed from '../ThirdPartyScriptEmbed'
|
|
||||||
import * as Types from '../types/${dir}'
|
|
||||||
`
|
|
||||||
for (const thirdParty of Object.values(config)) {
|
|
||||||
thirdPartyFunctions += generateComponent(thirdParty)
|
|
||||||
}
|
|
||||||
|
|
||||||
await Promise.all([
|
|
||||||
fs.writeFile(
|
|
||||||
path.join(dirPath, 'index.tsx'),
|
|
||||||
prettier.format(thirdPartyFunctions, { semi: false, parser: 'babel' })
|
|
||||||
),
|
|
||||||
])
|
|
||||||
}
|
|
||||||
})()
|
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
export type ScriptEmbed = {
|
export type ScriptEmbed = {
|
||||||
content?: string
|
html?: string | null
|
||||||
height?: number | null
|
height?: number | null
|
||||||
width?: number | null
|
width?: number | null
|
||||||
children?: React.ReactElement | React.ReactElement[]
|
children?: React.ReactElement | React.ReactElement[]
|
||||||
|
@ -9,7 +9,7 @@ export type ScriptEmbed = {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function ThirdPartyScriptEmbed({
|
export default function ThirdPartyScriptEmbed({
|
||||||
content,
|
html,
|
||||||
height = null,
|
height = null,
|
||||||
width = null,
|
width = null,
|
||||||
children,
|
children,
|
||||||
|
@ -19,17 +19,17 @@ export default function ThirdPartyScriptEmbed({
|
||||||
<>
|
<>
|
||||||
{/* insert script children */}
|
{/* insert script children */}
|
||||||
{children}
|
{children}
|
||||||
{/* insert content */}
|
{/* insert html */}
|
||||||
{content && (
|
{html ? (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
height: height != null ? `${height}px` : 'auto',
|
height: height != null ? `${height}px` : 'auto',
|
||||||
width: width != null ? `${width}px` : 'auto',
|
width: width != null ? `${width}px` : 'auto',
|
||||||
}}
|
}}
|
||||||
data-ntpc={dataNtpc}
|
data-ntpc={dataNtpc}
|
||||||
dangerouslySetInnerHTML={{ __html: content }}
|
dangerouslySetInnerHTML={{ __html: html }}
|
||||||
/>
|
/>
|
||||||
)}
|
) : null}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
20
packages/third-parties/src/google/GoogleMapsEmbed.tsx
Normal file
20
packages/third-parties/src/google/GoogleMapsEmbed.tsx
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import React from 'react'
|
||||||
|
import { GoogleMapsEmbed as TPCGoogleMapEmbed } from 'third-party-capital'
|
||||||
|
|
||||||
|
import ThirdPartyScriptEmbed from '../ThirdPartyScriptEmbed'
|
||||||
|
import { GoogleMapsEmbed as GoogleMapsEmbedTypes } from '../types/google'
|
||||||
|
|
||||||
|
export default function GoogleMapsEmbed(props: GoogleMapsEmbedTypes) {
|
||||||
|
const { apiKey, ...restProps } = props
|
||||||
|
const formattedProps = { ...restProps, key: apiKey }
|
||||||
|
const { html } = TPCGoogleMapEmbed(formattedProps)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ThirdPartyScriptEmbed
|
||||||
|
height={formattedProps.height || null}
|
||||||
|
width={formattedProps.width || null}
|
||||||
|
html={html}
|
||||||
|
dataNtpc="GoogleMapsEmbed"
|
||||||
|
></ThirdPartyScriptEmbed>
|
||||||
|
)
|
||||||
|
}
|
34
packages/third-parties/src/google/YouTubeEmbed.tsx
Normal file
34
packages/third-parties/src/google/YouTubeEmbed.tsx
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
import React from 'react'
|
||||||
|
import Script, { ScriptProps } from 'next/script'
|
||||||
|
import { YouTubeEmbed as TPCYouTubeEmbed } from 'third-party-capital'
|
||||||
|
|
||||||
|
import ThirdPartyScriptEmbed from '../ThirdPartyScriptEmbed'
|
||||||
|
import { YouTubeEmbed as YouTubeEmbedTypes } from '../types/google'
|
||||||
|
|
||||||
|
const scriptStrategy = {
|
||||||
|
server: 'beforeInteractive',
|
||||||
|
client: 'afterInteractive',
|
||||||
|
idle: 'lazyOnload',
|
||||||
|
worker: 'worker',
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function YouTubeEmbed(props: YouTubeEmbedTypes) {
|
||||||
|
const { html, scripts, stylesheets } = TPCYouTubeEmbed(props)
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ThirdPartyScriptEmbed
|
||||||
|
height={props.height || null}
|
||||||
|
width={props.width || null}
|
||||||
|
html={html}
|
||||||
|
dataNtpc="YouTubeEmbed"
|
||||||
|
>
|
||||||
|
{scripts?.map((script) => (
|
||||||
|
<Script
|
||||||
|
src={script.url}
|
||||||
|
strategy={scriptStrategy[script.strategy] as ScriptProps['strategy']}
|
||||||
|
stylesheets={stylesheets}
|
||||||
|
/>
|
||||||
|
))}
|
||||||
|
</ThirdPartyScriptEmbed>
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,39 +1,2 @@
|
||||||
/**
|
export { default as GoogleMapsEmbed } from './GoogleMapsEmbed'
|
||||||
* This is an autogenerated file by update-third-parties.js
|
export { default as YouTubeEmbed } from './YouTubeEmbed'
|
||||||
*/
|
|
||||||
import React from 'react'
|
|
||||||
import Script from 'next/script'
|
|
||||||
|
|
||||||
import ThirdPartyScriptEmbed from '../ThirdPartyScriptEmbed'
|
|
||||||
import * as Types from '../types/google'
|
|
||||||
|
|
||||||
// Embed a Google Maps embed on your webpage
|
|
||||||
export function GoogleMapsEmbed(args: Types.GoogleMapsEmbed) {
|
|
||||||
return (
|
|
||||||
<ThirdPartyScriptEmbed
|
|
||||||
height={args.height || null}
|
|
||||||
width={args.width || null}
|
|
||||||
content={`<iframe loading="lazy" src="https://www.google.com/maps/embed/v1/${args.mapMode}?key=${args.apiKey}&${args.parameters}" width=${args.width} height=${args.height} style=${args.style} allowfullscreen=${args.allowfullscreen} referrerpolicy="no-referrer-when-downgrade"></iframe>`}
|
|
||||||
dataNtpc="GoogleMapsEmbed"
|
|
||||||
></ThirdPartyScriptEmbed>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
// Embed a YouTube embed on your webpage.
|
|
||||||
export function YoutubeEmbed(args: Types.YoutubeEmbed) {
|
|
||||||
return (
|
|
||||||
<ThirdPartyScriptEmbed
|
|
||||||
height={args.height || null}
|
|
||||||
width={args.width || null}
|
|
||||||
content={`<lite-youtube videoid=${args.videoid} playlabel=${args.playlabel}></lite-youtube>`}
|
|
||||||
dataNtpc="YoutubeEmbed"
|
|
||||||
>
|
|
||||||
<Script
|
|
||||||
src={`https://cdn.jsdelivr.net/gh/paulirish/lite-youtube-embed@master/src/lite-yt-embed.js`}
|
|
||||||
strategy="lazyOnload"
|
|
||||||
stylesheets={[
|
|
||||||
'https://cdn.jsdelivr.net/gh/paulirish/lite-youtube-embed@master/src/lite-yt-embed.css',
|
|
||||||
]}
|
|
||||||
/>
|
|
||||||
</ThirdPartyScriptEmbed>
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
{
|
|
||||||
"google-maps-embed": "GoogleMapsEmbed",
|
|
||||||
"youtube-embed": "YoutubeEmbed"
|
|
||||||
}
|
|
|
@ -1,15 +1,20 @@
|
||||||
export type GoogleMapsEmbed = {
|
export type GoogleMapsEmbed = {
|
||||||
height?: number
|
height?: number
|
||||||
width?: number
|
width?: number
|
||||||
mapMode: 'place' | 'view' | 'directions' | 'streetview' | 'search'
|
mode: 'place' | 'view' | 'directions' | 'streetview' | 'search'
|
||||||
apiKey: string
|
apiKey: string
|
||||||
parameters: string
|
|
||||||
style: string
|
style: string
|
||||||
allowfullscreen: boolean
|
allowfullscreen: boolean
|
||||||
loading: 'eager' | 'lazy'
|
loading: 'eager' | 'lazy'
|
||||||
|
q?: string
|
||||||
|
center?: string
|
||||||
|
zoom?: string
|
||||||
|
maptype?: string
|
||||||
|
language?: string
|
||||||
|
region?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type YoutubeEmbed = {
|
export type YouTubeEmbed = {
|
||||||
height?: number
|
height?: number
|
||||||
width?: number
|
width?: number
|
||||||
videoid: string
|
videoid: string
|
||||||
|
|
|
@ -1678,8 +1678,8 @@ importers:
|
||||||
specifier: ^18.2.0
|
specifier: ^18.2.0
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
third-party-capital:
|
third-party-capital:
|
||||||
specifier: 1.0.17
|
specifier: 1.0.20
|
||||||
version: 1.0.17
|
version: 1.0.20
|
||||||
devDependencies:
|
devDependencies:
|
||||||
next:
|
next:
|
||||||
specifier: 13.4.20-canary.12
|
specifier: 13.4.20-canary.12
|
||||||
|
@ -25414,8 +25414,8 @@ packages:
|
||||||
/text-table@0.2.0:
|
/text-table@0.2.0:
|
||||||
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==}
|
||||||
|
|
||||||
/third-party-capital@1.0.17:
|
/third-party-capital@1.0.20:
|
||||||
resolution: {integrity: sha512-TOoAmaUg1sYZNErMrsEdEp8BSgtnnJL9nhHwisv3kZ2d1Ze0Cjj4zdv/qgwhVPqMvecTI3ZNxhrKSvkYEY2qtg==}
|
resolution: {integrity: sha512-oB7yIimd8SuGptespDAZnNkzIz+NWaJCu2RMsbs4Wmp9zSDUM8Nhi3s2OOcqYuv3mN4hitXc8DVx+LyUmbUDiA==}
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/throat@6.0.1:
|
/throat@6.0.1:
|
||||||
|
|
|
@ -8,8 +8,9 @@ const Page = () => {
|
||||||
apiKey="XYZ"
|
apiKey="XYZ"
|
||||||
height={200}
|
height={200}
|
||||||
width="100%"
|
width="100%"
|
||||||
mapMode="place"
|
mode="place"
|
||||||
parameters="q=Brooklyn+Bridge,New+York,NY"
|
id="maps-embed"
|
||||||
|
q="Brooklyn+Bridge,New+York,NY"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { YoutubeEmbed } from '@next/third-parties/google'
|
import { YouTubeEmbed } from '@next/third-parties/google'
|
||||||
|
|
||||||
const Page = () => {
|
const Page = () => {
|
||||||
return (
|
return (
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Youtube Embed</h1>
|
<h1>Youtube Embed</h1>
|
||||||
<YoutubeEmbed videoid="ogfYd705cRs" height={400} />
|
<YouTubeEmbed videoid="ogfYd705cRs" height={400} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ createNextDescribe(
|
||||||
it('renders YoutubeEmbed', async () => {
|
it('renders YoutubeEmbed', async () => {
|
||||||
const $ = await next.render$('/youtube-embed')
|
const $ = await next.render$('/youtube-embed')
|
||||||
|
|
||||||
const baseContainer = $('[data-ntpc="YoutubeEmbed"]')
|
const baseContainer = $('[data-ntpc="YouTubeEmbed"]')
|
||||||
const youtubeContainer = $('lite-youtube')
|
const youtubeContainer = $('lite-youtube')
|
||||||
expect(baseContainer.length).toBe(1)
|
expect(baseContainer.length).toBe(1)
|
||||||
expect(youtubeContainer.length).toBe(1)
|
expect(youtubeContainer.length).toBe(1)
|
||||||
|
@ -22,8 +22,9 @@ createNextDescribe(
|
||||||
const $ = await next.render$('/google-maps-embed')
|
const $ = await next.render$('/google-maps-embed')
|
||||||
|
|
||||||
const baseContainer = $('[data-ntpc="GoogleMapsEmbed"]')
|
const baseContainer = $('[data-ntpc="GoogleMapsEmbed"]')
|
||||||
|
|
||||||
const mapContainer = $(
|
const mapContainer = $(
|
||||||
'[src="https://www.google.com/maps/embed/v1/place?key=XYZ&q=Brooklyn+Bridge,New+York,NY"]'
|
'[src^="https://www.google.com/maps/embed/v1/place?key=XYZ"]'
|
||||||
)
|
)
|
||||||
expect(baseContainer.length).toBe(1)
|
expect(baseContainer.length).toBe(1)
|
||||||
expect(mapContainer.length).toBe(1)
|
expect(mapContainer.length).toBe(1)
|
||||||
|
|
|
@ -12,7 +12,7 @@ createNextDescribe(
|
||||||
it('renders YoutubeEmbed', async () => {
|
it('renders YoutubeEmbed', async () => {
|
||||||
const $ = await next.render$('/youtube-embed')
|
const $ = await next.render$('/youtube-embed')
|
||||||
|
|
||||||
const baseContainer = $('[data-ntpc="YoutubeEmbed"]')
|
const baseContainer = $('[data-ntpc="YouTubeEmbed"]')
|
||||||
const youtubeContainer = $('lite-youtube')
|
const youtubeContainer = $('lite-youtube')
|
||||||
expect(baseContainer.length).toBe(1)
|
expect(baseContainer.length).toBe(1)
|
||||||
expect(youtubeContainer.length).toBe(1)
|
expect(youtubeContainer.length).toBe(1)
|
||||||
|
@ -23,7 +23,7 @@ createNextDescribe(
|
||||||
|
|
||||||
const baseContainer = $('[data-ntpc="GoogleMapsEmbed"]')
|
const baseContainer = $('[data-ntpc="GoogleMapsEmbed"]')
|
||||||
const mapContainer = $(
|
const mapContainer = $(
|
||||||
'[src="https://www.google.com/maps/embed/v1/place?key=XYZ&q=Brooklyn+Bridge,New+York,NY"]'
|
'[src^="https://www.google.com/maps/embed/v1/place?key=XYZ"]'
|
||||||
)
|
)
|
||||||
expect(baseContainer.length).toBe(1)
|
expect(baseContainer.length).toBe(1)
|
||||||
expect(mapContainer.length).toBe(1)
|
expect(mapContainer.length).toBe(1)
|
||||||
|
|
|
@ -8,8 +8,8 @@ const Page = () => {
|
||||||
apiKey="XYZ"
|
apiKey="XYZ"
|
||||||
height={200}
|
height={200}
|
||||||
width="100%"
|
width="100%"
|
||||||
mapMode="place"
|
mode="place"
|
||||||
parameters="q=Brooklyn+Bridge,New+York,NY"
|
q="Brooklyn+Bridge,New+York,NY"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
import { YoutubeEmbed } from '@next/third-parties/google'
|
import { YouTubeEmbed } from '@next/third-parties/google'
|
||||||
|
|
||||||
const Page = () => {
|
const Page = () => {
|
||||||
return (
|
return (
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<h1>Youtube Embed</h1>
|
<h1>Youtube Embed</h1>
|
||||||
<YoutubeEmbed videoid="ogfYd705cRs" height={400} />
|
<YouTubeEmbed videoid="ogfYd705cRs" height={400} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue