Skip to content

Commit

Permalink
Merge branch 'main' of github.com:nuxt/scripts
Browse files Browse the repository at this point in the history
  • Loading branch information
harlan-zw committed Jun 4, 2024
2 parents 08027ed + d637151 commit b09e64a
Show file tree
Hide file tree
Showing 8 changed files with 400 additions and 10 deletions.
205 changes: 205 additions & 0 deletions docs/content/scripts/ads/carbon-ads.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,205 @@
---
title: Carbon Ads
description: Show carbon ads in your Nuxt app using a Vue component.
links:
- label: "<ScriptCarbonAds>"
icon: i-simple-icons-github
to: https://github.com/nuxt/scripts/blob/main/src/runtime/components/ScriptCarbonAds.vue
size: xs
---

[Carbon Ads](https://www.carbonads.net/) is an ad service that provides a performance friendly way to show ads on your site.

Nuxt Scripts provides a headless `ScriptCarbonAds` component to embed Carbon Ads in your Nuxt app.

## ScriptCarbonAds

The `ScriptCarbonAds` component works differently to other Nuxt Scripts component and does not rely on `useScript`, instead it simply
inserts a script tag into the div of the component on mount.

By default, the component uses CarbonAds best practices which is to load immediately on mount. You can make use of [Element Event Triggers](/docs/guides/script-triggers#element-event-triggers) if you
want to load the ads on a specific event.

```vue
<template>
<ScriptCarbonAds
serve="..."
placement="..."
/>
</template>
```

### Handling Ad-blockers

You can use these hooks to add a fallback when CarbonAds is blocked.

```vue
<template>
<ScriptCarbonAds
serve="..."
placement="..."
>
<template #error>
<!-- Fallback ad -->
Please support us by disabling your ad blocker.
</template>
</ScriptCarbonAds>
</template>
```

### Adding UI

The component renders as headless, meaning there is no inherit styles. If you'd like to customize the look of the ad, you can
use this example from nuxt.com.

```vue
<template>
<ScriptCarbonAds
class="Carbon border border-gray-200 dark:border-gray-800 rounded-lg bg-white dark:bg-white/5"
serve="..."
placement="..."
/>
</template>
<style lang="postcss">
/* Credits to nuxt.com */
.dark .Carbon {
min-height: 220px;
.carbon-text {
@apply text-gray-400;
&:hover {
@apply text-gray-200;
}
}
}
.light .Carbon {
.carbon-text {
@apply text-gray-600;
&:hover {
@apply text-gray-800;
}
}
}
.Carbon {
@apply p-3 flex flex-col max-w-full;
@screen sm {
@apply max-w-xs;
}
@screen lg {
@apply mt-0;
}
#carbonads span {
@apply flex flex-col justify-between;
.carbon-wrap {
@apply flex flex-col;
flex: 1;
@media (min-width: 320px) {
@apply flex-row;
}
@screen lg {
@apply flex-col;
}
.carbon-img {
@apply flex items-start justify-center mb-4;
@media (min-width: 320px) {
@apply mb-0;
}
@screen lg {
@apply mb-4;
}
}
.carbon-text {
@apply flex-1 text-sm w-full m-0 text-left block;
&:hover {
@apply no-underline;
}
@media (min-width: 320px) {
@apply ml-4;
}
@screen lg {
@apply ml-0;
}
}
}
}
img {
@apply w-full;
}
& .carbon-poweredby {
@apply ml-2 text-xs text-right text-gray-400 block pt-2;
&:hover {
@apply no-underline text-gray-500;
}
}
}
</style>
```

### Props

The `ScriptCarbonAds` component accepts the following props:

- `serve`: The serve URL provided by Carbon Ads.
- `placement`: The placement ID provided by Carbon Ads.
- `trigger`: The trigger event to load the script. Default is `undefined`. See [Element Event Triggers](/docs/guides/script-triggers#element-event-triggers) for more information.

### Events

The component emits the script events.

```ts
const emits = defineEmits<{
error: [e: string | Event]
load: []
}>()
```

### Slots

There are a number of slots mapped to the script status that you can use to customize the ad experience.

- **error**:
The slot is used to display content when the ad fails to load.

- **awaitingLoad**
The slot is used to display content before the ad script is loaded.

- **loaded**
The slot is used to display content after the ad script is loaded.

- **loading**
The slot is used to display content while the ad script is loading.

```vue
<template>
<ScriptCarbonAds
serve="..."
placement="..."
>
<template #awaitingLoad>
Loading ads...
</template>
</ScriptCarbonAds>
</template>
```
108 changes: 108 additions & 0 deletions playground/pages/third-parties/carbon/nuxt-scripts.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
<template>
<ScriptCarbonAds
class="Carbon border border-gray-200 dark:border-gray-800 rounded-lg bg-white dark:bg-white/5"
serve="CW7DTKJL"
placement="unlighthousedev"
>
<template #awaitingLoad>
<div>waiting for carbon</div>
</template>
<template #error>
<div>Please enable ads</div>
</template>
</ScriptCarbonAds>
</template>

<style lang="postcss">
/* Credits to nuxt.com */
.dark .Carbon {
min-height: 220px;
.carbon-text {
@apply text-gray-400;
&:hover {
@apply text-gray-200;
}
}
}
.light .Carbon {
.carbon-text {
@apply text-gray-600;
&:hover {
@apply text-gray-800;
}
}
}
.Carbon {
@apply p-3 flex flex-col max-w-full;
@screen sm {
@apply max-w-xs;
}
@screen lg {
@apply mt-0;
}
#carbonads span {
@apply flex flex-col justify-between;
.carbon-wrap {
@apply flex flex-col;
flex: 1;
@media (min-width: 320px) {
@apply flex-row;
}
@screen lg {
@apply flex-col;
}
.carbon-img {
@apply flex items-start justify-center mb-4;
@media (min-width: 320px) {
@apply mb-0;
}
@screen lg {
@apply mb-4;
}
}
.carbon-text {
@apply flex-1 text-sm w-full m-0 text-left block;
&:hover {
@apply no-underline;
}
@media (min-width: 320px) {
@apply ml-4;
}
@screen lg {
@apply ml-0;
}
}
}
}
img {
@apply w-full;
}
& .carbon-poweredby {
@apply ml-2 text-xs text-right text-gray-400 block pt-2;
&:hover {
@apply no-underline text-gray-500;
}
}
}
</style>
14 changes: 8 additions & 6 deletions src/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import type {
NuxtConfigScriptRegistry,
NuxtUseScriptInput,
NuxtUseScriptOptions,
RegistryScript,
RegistryScripts,
} from './runtime/types'

Expand Down Expand Up @@ -128,15 +129,16 @@ export default defineNuxtModule<ModuleOptions>({
const registryScripts = [...scripts]
// @ts-expect-error runtime
await nuxt.hooks.callHook('scripts:registry', registryScripts)
addImports(registryScripts.map((i) => {
const withComposables = registryScripts.filter(i => !!i.import?.name) as Required<RegistryScript>[]
addImports(withComposables.map((i) => {
return {
priority: -1,
...i.import,
}
}))

// compare the registryScripts to the original registry to find new scripts
const newScripts = registryScripts.filter(i => !scripts.some(r => r.import.name === i.import.name))
const newScripts = withComposables.filter(i => !scripts.some(r => r.import?.name === i.import.name))

// augment types to support the integrations registry
extendTypes(name!, async ({ typesPath }) => {
Expand All @@ -156,9 +158,9 @@ declare module '#nuxt-scripts' {
type NuxtUseScriptOptions = Omit<import('${typesPath}').NuxtUseScriptOptions, 'use' | 'beforeInit'>
interface ScriptRegistry {
${newScripts.map((i) => {
const key = i.import.name.replace('useScript', '')
const key = i.import?.name.replace('useScript', '')
const keyLcFirst = key.substring(0, 1).toLowerCase() + key.substring(1)
return ` ${keyLcFirst}?: import('${i.import.from}').${key}Input | [import('${i.import.from}').${key}Input, NuxtUseScriptOptions]`
return ` ${keyLcFirst}?: import('${i.import?.from}').${key}Input | [import('${i.import?.from}').${key}Input, NuxtUseScriptOptions]`
}).join('\n')}
}
}`
Expand All @@ -176,7 +178,7 @@ ${newScripts.map((i) => {
const inits = []
// for global scripts, we can initialise them script away
for (const [k, c] of Object.entries(config.registry || {})) {
const importDefinition = registryScripts.find(i => i.import.name === `useScript${k.substring(0, 1).toUpperCase() + k.substring(1)}`)
const importDefinition = withComposables.find(i => i.import.name === `useScript${k.substring(0, 1).toUpperCase() + k.substring(1)}`)
if (importDefinition) {
// title case
imports.unshift(importDefinition.import.name)
Expand Down Expand Up @@ -206,7 +208,7 @@ ${(config.globals || []).map(g => !Array.isArray(g)

const moduleInstallPromises: Map<string, () => Promise<boolean> | undefined> = new Map()
addBuildPlugin(NuxtScriptBundleTransformer({
scripts,
scripts: withComposables,
defaultBundle: config.defaultScriptOptions?.bundle,
moduleDetected(module) {
if (nuxt.options.dev && module !== '@nuxt/scripts' && !moduleInstallPromises.has(module) && !hasNuxtModule(module))
Expand Down
4 changes: 2 additions & 2 deletions src/plugins/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@ import type { Node } from 'estree-walker'
import { walk } from 'estree-walker'
import type { Literal, ObjectExpression, Property, SimpleCallExpression } from 'estree'
import type { Input } from 'valibot'
import type { RegistryScripts } from '#nuxt-scripts'
import type { RegistryScript } from '#nuxt-scripts'

export interface AssetBundlerTransformerOptions {
resolveScript: (src: string) => string
moduleDetected?: (module: string) => void
defaultBundle?: boolean
scripts?: RegistryScripts
scripts?: Required<RegistryScript>[]
}

export function NuxtScriptBundleTransformer(options: AssetBundlerTransformerOptions) {
Expand Down
6 changes: 6 additions & 0 deletions src/registry.ts

Large diffs are not rendered by default.

0 comments on commit b09e64a

Please sign in to comment.