🚀 We're launching Video Optimization in beta! Read the announcement.

Vue 3

vuejs-cover
Use TwicPics Vue 3 Components to get images and videos integration best practices out-of-the-box.

You can find usage examples in our online demo project.

Installation

Add the @twicpics/components package to your project:

# Using yarn
yarn add @twicpics/components
# Or using npm
npm install @twicpics/components

Setup

Setting-up TwicPics Components into your Vue3 project

TwicPics components for Vue3 comes as an Vue3 Plugin and is configured as such.

You will need a TwicPics domain to initialize the package. Create an account for free to get your domain.

Add the import part

// import TwicPics vue3 plugin
import TwicPics from '@twicpics/components/vue3'
// import TwicPics components css
import '@twicpics/components/style.css'

and use TwicPics Components Plugin with Setup Options

// app is the application instance
app.use(TwicPics, {
  domain: 'https://<your-domain>.twic.pics'
})

into the app startup of your Vue3 project.

main.js

// Here is an example of a `Vue3` app startup configured with TwicPics.
import App from './App.vue'
import { createApp } from 'vue'

// import TwicPics Vue3 Plugin
import TwicPics from '@twicpics/components/vue3'
import '@twicpics/components/style.css'

// create application instance
const app = createApp(App)

// configure TwicPics Vue3 Plugin
app.use(TwicPics, {
  domain: 'https://<your-domain>.twic.pics'
})

app.mount('#app')

Changing components names

You can change how components are named using the TwicImg and/or TwicVideo options when calling use:

app.use(TwicPics, {
  // domain is mandatory
  domain: 'https://<your-domain>.twic.pics',
  TwicImg: 'Batman'
})

You can then reference the component using the alternate name:

<template>
  <Batman src="path/to/your/image" />
</template>

Setup Options

OptionDescriptionTypeDefault
anticipationTwicPics will lazy-load images by default. To avoid too abrupt a transition with elements appearing into view and then images very obviously loading afterwards, TwicPics will "anticipate" lazy loading by a factor of the actual viewport. This behavior is controlled by this setting.Number0.2
domainThis is your very own TwicPics domain. Providing it is mandatory.String
envCan be debug, offline or production. When set to debug, a gray lightweight svg placeholder that displays its intrinsic dimensions is displayed in place of all medias targeted by their src value. When set to offline, these medias are replaced by a simple placeholder that allows to visualise their display area.String"production"
handleShadowDomMust be set to true when using TwicComponents within a shadow DOM.booleanfalse
maxDPRTwicPics will take the "Device Pixel Ratio" (DPR) of the current device into consideration when determining the sizes of images to load. By default, it will not take a DPR greater than 2 into consideration. If the DPR of the device is higher than 2, TwicPics will assume it to be 2. Using maxDPR, you can lower this limit down to 1 or be more permissive (for instance by setting it to 3 or 4).Number2
pathPath to prepend to all src attributes. For instance, if path is "some/folder" then a src attribute set to "image.jpg" will be expanded into "some/folder/image.jpg"String
stepTo avoid requesting too may variants of the same image, TwicPics will round the width of images to the closest multiple of step. The height will then be computed in order to respect the original aspect ratio.Integer10

Usage

TwicImg and TwicVideo are available in your templates as long as you have configured the TwicPics Vue3 Plugin.

Just use them in your template files in place of img or video tags (see Components Properties).

<template>
  <main>
    <TwicImg src="path/to/your/image" />
  </main>
</template>

Basic usage

<!-- component.vue -->
<template>
  <main>
    <TwicImg src="path/to/your/image" />
  </main>
</template>

Open in StackBlitz

Bulk loading with TwicView

By default, <TwicImg> and <TwicVideo> will only start loading when they come into the viewport. But sometimes, you may want to load multiple assets in bulk instead of lazy loading them. This is where <TwicView> comes into play.

The <TwicView> components eager loads all of his <TwicImg> and <TwicVideo> children as soon as it comes into the viewport (depending on your anticipation settings.)

For example, if you're building a carousel, you might want to bulk load all images. In the following code, all three images will be loaded when TwicView comes into the viewport:

<TwicView>
  <TwicImg src="image1.jpg" />
  <TwicImg src="image2.jpg" />
  <TwicImg src="image3.jpg" />
</TwicView>

Open in StackBlitz

Style-Driven Approach

You can set up components using pure CSS and the power of CSS variables

<!-- component.vue -->
<template>
  <main>
    <div class="twic-item landscape">
      <TwicImg src="path/to/your/image"></TwicImg>
    </div>
    <div class="twic-item square">
      <TwicImg src="path/to/your/image"></TwicImg>
    </div>
    <div class="twic-item portrait">
      <TwicImg src="path/to/your/image"></TwicImg>
    </div>
    <div class="twic-item contain left">
      <TwicImg src="path/to/your/image" ratio="16/9"></TwicImg>
    </div>
    <div class="twic-item contain right">
      <TwicImg src="path/to/your/image" ratio="16/9"></TwicImg>
    </div>
    <div class="twic-item lg">
      <TwicImg src="path/to/your/image"></TwicImg>
    </div>
    <div class="twic-item md">
      <TwicImg src="path/to/your/image"></TwicImg>
    </div>
    <div class="twic-item sm">
      <TwicImg src="path/to/your/image"></TwicImg>
    </div>
    <!--- Attributes take precedence over CSS.
    In the next example, ratio will 16/9 AND 
    NOT 1 as defined in square css class --->
    <div class="cover square">
      <TwicImg src="path/to/your/image" ratio="16/9"></TwicImg>
    </div>
  </main>
</template>

<script>
  export default {
    name: 'App'
  }
</script>

<style>
  .landscape {
    --twic-ratio: calc(4 / 3);
  }
  .portrait {
    --twic-ratio: calc(3 / 4);
  }
  .square {
    --twic-ratio: calc(1);
  }

  .lg {
    width: 300px;
  }

  .md {
    width: 150px;
  }

  .sm {
    width: 100px;
  }
</style>

Open in StackBlitz

Responsive Example

Setting up components using CSS and CSS variables enables hassle-free responsive designs.

<!-- component.vue -->
<template>
  <main>
    <div class="style-driven-responsive">
      <TwicImg src="path/to/your/image"></TwicImg>
    </div>
  </main>
</template>

<script>
  export default {
    name: 'App'
  }
</script>

<style>
  .style-driven-responsive {
    --twic-ratio: calc(2 / 3);
    --twic-mode: cover;
    margin: auto;
  }

  @media (min-width: 640px) {
    .style-driven-responsive {
      --twic-ratio: calc(1);
    }
  }

  @media (min-width: 768px) {
    .style-driven-responsive {
      --twic-ratio: calc(4 / 3);
    }
  }

  @media (min-width: 1024px) {
    .style-driven-responsive {
      --twic-ratio: calc(16 / 9);
    }
  }

  @media (min-width: 1280px) {
    .style-driven-responsive {
      --twic-ratio: calc(1.85);
    }
  }

  @media (min-width: 1536px) {
    .style-driven-responsive {
      --twic-ratio: calc(21 / 9);
    }
  }
</style>

Your template features a single component that will follow your CSS directives and behave responsively.

Open in StackBlitz

Working with ratio="none"

Particularly useful when creating hero banner, you can specify the height of your image while respecting its natural aspect ratio and optimizing your Cumulative Layout Shift (CLS) metric.

<!-- component.vue -->
<template>
  <TwicImg src="path/to/your/image" class="hero-image" ratio="none"></TwicImg>
</template>

<script>
  export default {
    name: 'App'
  }
</script>

<style>
  /* You are responsible for properly sizing the component. */
  .hero-image {
    height: 500px;
  }

  @media (min-width: 1024px) {
    .hero-image {
      height: 300px;
      width: 100%;
    }
  }
</style>

Open in StackBlitz

Lifecycle

Passing a callback function to stateChange emitter gives access to the loading state of your image or video.

Here are the values the Component will emit (see State Type definition) :

  • new: when the img or video source has not started loading
  • loading: when the img or video source is loading
  • done: when the img or video source has successfully loaded
  • error: when an error occurred while loading the img or video source
<!-- component.vue -->
<template>
  <main>
    <div class="style-driven-responsive">
      <TwicImg src="path/to/your/image" @stateChange="handleStateChange" />
    </div>
  </main>
</template>

<script>
  export default {
    name: 'App',
    data() {
      state: undefined
    },
    methods: {
      handleStateChange(stateEvent) {
        // Implement the logic here
        const { state } = stateEvent
        this.state = state
        console.log(`TwicComponent emits a new state`, this.state)
      }
    }
  }
</script>

Open in StackBlitz

Components Properties

TwicImg

This component can be used in place of an img element.

<TwicImg
  src="<path>"
  alt="<String>"
  anchor="<String>"
  bot="<String>"
  eager="<boolean>"
  focus="<auto|coordinates>"
  intrinsic="<String>"
  mode="<contain|cover>"
  position="<css position>"
  placeholder="<preview|maincolor|meancolor|none>"
  preTransform="<String>"
  ratio="<ratio>"
  @stateChange="<function>"
  step="<integer>"
  transition="<fade|zoom|none>"
  transitionDelay="<String>"
  transitionDuration="<String>"
  transitionTimingFunction="<String>"
/>
AttributeDescriptionTypeDefault
altalt attribute contentStringbased on src
anchorPositions the image in both contain and cover mode. Accepted values are top, bottom, left, right, top-left, top-right, bottom-left and bottom-right. position and focus take precedence in contain and cover mode respectively. Please note that anchor is applied after an eventual preTransform.String
botA slash-separated list of TwicPics API transformations to be performed for search engine bots. This overrides all other transformations when provided, even if empty (i.e bot=""). See the TwicPics bot attribute documentation for more information.String
eagerLoad the image as soon as the component is mounted. This effectively means disabling lazy loading for this image.booleanfalse
focusSets the focus point in cover mode. focus takes precedence over anchor when both are provided. See the TwicPics focus attribute documentation for more information. Only use this attribute if you need a specific focus point or if you want to leverage smart cropping with focus="auto": if you only need border-based positionning (top, bottom, left, right, etc), use anchor instead.String
intrinsicDimensions in pixels of the original image, formatted <width>x<height> (eg. 1920x1080). It prevents image upscaling and limits the number of generated variants. If using preTransform, you should specify the intrinsic dimensions of the resulting image. Using incorrect values can lead to display issues, see the intrinsic attribute documentation.String
modeCan be contain or cover and determines if the image fills the area and is cropped accordingly (cover) or if the image will sit inside the area with no cropping (contain).Stringcover
placeholderCan be preview, meancolor, maincolor or none. See the TwicPics output transformation documentation for more information. Setting will be overridden to none when using zoom transition.Stringpreview
positionPositions the image in contain mode. position takes precedence over anchor when both are provided. Syntax is the same as for CSS position properties background-position and object-position. Only use this attribute if you need precise positionning: if you only need border-based positionning (top, bottom, left, right, etc), use anchor instead.Stringcenter
preTransformA slash-separated list of TwicPics API transformations to be performed before resizing the image (see the TwicPics Manipulation documentation). Note that anchor and focus are applied after preTransform: if you need to specify a specific focus point for your preTransform then it needs to be part of the expression (like preTransform="focus=auto/crop=50px50p" for instance). Be aware that using this option can lead to unexpected results so use with caution!String
ratioA unitless width/height or width:height value pair (as in 4/3 or 4:3) that defines the aspect ratio of the display area. If height is not specified, it is assumed to be 1. A square area will be created by default. When set to none, ratio is determined based on width and height as computed by the browser following your CSS definitions. The --twic-ratio CSS variable is ignored in this instance. You are responsible for properly sizing the component when ratio="none".String1
srcPath to the image. When not provided, a red lightweight svg placeholder that displays its intrinsic dimensions is displayed in place of the absent image. When env is set to offline, that red lightweight svg is replaced by a simple red placeholder.String
stateChangeAn event dispatched each time the image loading state is updated. State can be new, loading, done or error.( stateEvent: StateEvent ) => void
stepSee the TwicPics step attribute documentation for more information.Integer10
transitionDetermines how the image will be revealed once loaded. With a fade in effect (fade), a zoom effect (zoom) or without any transition (none). Unsupported values are handled as fade.Stringfade
transitionDurationDuration of the transition effect.String400ms
transitionTimingFunctionCSS timing function applied to the transition effect.Stringease
transitionDelayTransition delay of the transition effect.String0ms

TwicVideo

This component can be used in place of a video element.

<TwicVideo
  src="<path>"
  anchor="<String>"
  bot="<String>"
  eager="<boolean>"
  focus="<auto|coordinates>"
  intrinsic="<String>"
  mode="<contain|cover>"
  position="<css position>"
  placeholder="<preview|maincolor|meancolor|none>"
  preTransform="<String>"
  ratio="<ratio>"
  @stateChange="<function>"
  step="<integer>"
  transition="<fade|zoom|none>"
  transitionDelay="<String>"
  transitionDuration="<String>"
  transitionTimingFunction="<String>"
/>
AttributeDescriptionTypeDefault
altalt attribute contentStringbased on src
anchorPositions the video in both contain and cover mode. Accepted values are top, bottom, left, right, top-left, top-right, bottom-left and bottom-right. position and focus take precedence in contain and cover mode respectively. Please note that anchor is applied after an eventual preTransform.String
botA slash-separated list of TwicPics API transformations to be performed for search engine bots. This overrides all other transformations when provided, even if empty (i.e bot=""). See the TwicPics bot attribute documentation for more information.String
eagerLoad the image as soon as the component is mounted. This effectively means disabling lazy loading for this image.booleanfalse
focusSets the focus point in cover mode. focus takes precedence over anchor when both are provided. See the TwicPics focus attribute documentation for more information. Only use this attribute if you need a specific focus point or if you want to leverage smart cropping with focus="auto": if you only need border-based positionning (top, bottom, left, right, etc), use anchor instead.String
intrinsicDimensions in pixels of the original video, formatted <width>x<height> (eg. 1920x1080). It prevents video upscaling and limits the number of generated variants. If using preTransform, you should specify the intrinsic dimensions of the resulting video. Using incorrect values can lead to display issues, see the intrinsic attribute documentation.String
modeCan be contain or cover and determines if the video fills the area and is cropped accordingly (cover) or if the video will sit inside the area with no cropping (contain).Stringcover
placeholderCan be preview, meancolor, maincolor or none. See the TwicPics output transformation documentation for more information. Setting will be overridden to none when using zoom transition.Stringpreview
positionPositions the video in contain mode. position takes precedence over anchor when both are provided. Syntax is the same as for CSS position properties background-position and object-position. Only use this attribute if you need precise positionning: if you only need border-based positionning (top, bottom, left, right, etc), use anchor instead.Stringcenter
preTransformA slash-separated list of TwicPics API transformations to be performed before resizing the video (see the TwicPics Manipulation documentation). Note that anchor and focus are applied after preTransform: if you need to specify a specific focus point for your preTransform then it needs to be part of the expression (like preTransform="focus=auto/crop=50px50p" for instance). Be aware that using this option can lead to unexpected results so use with caution!String
ratioA unitless width/height or width:height value pair (as in 4/3 or 4:3) that defines the aspect ratio of the display area. If height is not specified, it is assumed to be 1. A square area will be created by default. When set to none, ratio is determined based on width and height as computed by the browser following your CSS definitions. The --twic-ratio CSS variable is ignored in this instance. You are responsible for properly sizing the component when ratio="none".String1
srcPath to the video. When not provided, a red lightweight svg placeholder that displays its intrinsic dimensions is displayed in place of the absent video. When env is set to offline, that red lightweight svg is replaced by a simple red placeholder.String
stateChangeAn event dispatched each time the video loading state is updated. State can be new, loading, done or error.( stateEvent: StateEvent ) => void
stepSee the TwicPics step attribute documentation for more information.Integer10
transitionDetermines how the video will be revealed once loaded. With a fade in effect (fade), a zoom effect (zoom) or without any transition (none). Unsupported values are handled as fade.Stringfade
transitionDurationDuration of the transition effect.String400ms
transitionTimingFunctionCSS timing function applied to the transition effect.Stringease
transitionDelayTransition delay of the transition effect.String0ms

Loading State Values

Union type for all possible image or video loading state.

type State = `error` | `done` | `loading` | `new`
  • new: when the img or video source has not started loading
  • loading: when the img or video source is loading
  • done: when the img or video source has successfully loaded
  • error: when an error occurred while loading the img or video source

State Change Event

Data type passed as parameter to stateChange emitter.

export type StateEvent = {
  target: TwicImg | TwicVideo
  state: State
}

CSS Variables

List of variables that can be used to configure your components using pure CSS.

<selector > {
  --twic-ratio: <ratio>;
  --twic-mode: <contain|cover>;
  --twic-position: <css position>;
  --twic-transition-delay: <string>;
  --twic-transition-duration: <string>;
  --twic-transition-timing-function: <string>;
}

Each CSS variable corresponds to one of the components attributes listed in the Components Properties section. If present, the attribute takes precedence over the corresponding CSS variable.

VariableDescriptionHTML AttributeDefault
--twic-modeCan be contain or cover and determines if the image fills the area and is cropped accordingly (cover) or if the image will sit inside the area with no cropping (contain).modecover
--twic-positionOnly useful in contain mode. Locates the image inside the area. Syntax is the same as for CSS position properties like background-position or object-position. Useful values are top, bottom, left, right, left top, left bottom and so on.positioncenter
--twic-ratioFloating point value corresponding to a unitless width/height ratio (as in calc(4/3) or 1.333). Ratio will correspond to a square area by default.ratio1
--twic-transition-delayTransition delay of the transition effect.transitionDelay0ms
--twic-transition-durationDuration of the transition effect.transitionDuration400ms
--twic-transition-timing-functionCSS timing function applied to the transition effect.transitionTimingFunctionease

Feedback and support

TwicPics Components are open-source on GitHub. For features requests and bugs, open an issue. The TwicPics team also remains available for support via the live chat (at the bottom right.)

responsive images

The All-In-One Toolbox For Your Medias

The simplest, most powerful way to tackle responsive images & videos