# Integration with Hugo


[Hugo](https://gohugo.io/) is a fast and modern static site generator written in Go. Kinescope provides a ready-made shortcode for conveniently embedding video and playlists in Hugo documentation and blogs.

## **When you'll need the Hugo integration**

Use the Hugo integration if:

- **Documentation on Hugo** — you want to embed video in your documentation
- **Blog on Hugo** — you need to add video to blog posts
- **Uniform embedding** — all videos and playlists are embedded the same way via a simple shortcode
- **Responsive** — players automatically adapt to the container width
- **Performance** — lazy loading for optimized page load times

If you use Hugo for documentation or a blog — read on. Below you'll find how to set up the integration in a few minutes.

## **How the shortcode works (4 steps)**

1. **Install the shortcode** — add the shortcode file to your theme or project
2. **Use the shortcode in Markdown** — insert a simple command instead of HTML code
3. **Hugo processes the shortcode** — during site build, it generates the correct HTML with an iframe
4. **Video displays on the page** — the responsive player automatically adapts to the container

Now let's walk through how to set it up.

## **Setup: step 1 — install the shortcode**

The `kinescope` shortcode is already included in the Kinescope documentation theme. If you're using your own theme or want to add it to an existing Hugo project:

1. **Create the shortcode file** in your theme directory:

```bash
themes/your-theme/layouts/shortcodes/kinescope.html
```

Or in the project root (if you're not using a theme):

```bash
layouts/shortcodes/kinescope.html
```

2. **Create the file with the following content:**

```html
{{- /* 
  Shortcode for embedding Kinescope players (video and playlists)
*/ -}}

{{- $url := .Get "url" -}}
{{- $id := .Get "id" -}}
{{- $type := .Get "type" | default "" -}}
{{- $width := .Get "width" -}}
{{- $height := .Get "height" -}}
{{- $ratio := .Get "ratio" | default "56.25" -}}
{{- $allow := .Get "allow" | default "autoplay; fullscreen; picture-in-picture; encrypted-media; gyroscope; accelerometer; clipboard-write; screen-wake-lock;" -}}

{{- /* Validation: either url or id must be specified */ -}}
{{- if and (not $url) (not $id) -}}
  {{- errorf "kinescope shortcode: either 'url' or 'id' parameter is required" -}}
{{- end -}}

{{- /* Determine embed URL */ -}}
{{- $embedUrl := "" -}}
{{- if $url -}}
  {{- if strings.HasPrefix $url "https://kinescope.io/embed/" -}}
    {{- $embedUrl = $url -}}
  {{- else if strings.HasPrefix $url "https://kinescope.io/pl/" -}}
    {{- $embedUrl = strings.Replace $url "https://kinescope.io/pl/" "https://kinescope.io/embed/pl/" 1 -}}
  {{- else if strings.HasPrefix $url "https://kinescope.io/" -}}
    {{- $embedUrl = strings.Replace $url "https://kinescope.io/" "https://kinescope.io/embed/" 1 -}}
  {{- else -}}
    {{- errorf "kinescope shortcode: unsupported URL format: %s" $url -}}
  {{- end -}}
{{- else if $id -}}
  {{- if eq $type "pl" -}}
    {{- $embedUrl = printf "https://kinescope.io/embed/pl/%s" $id -}}
  {{- else -}}
    {{- $embedUrl = printf "https://kinescope.io/embed/%s" $id -}}
  {{- end -}}
{{- end -}}

{{- /* Build query parameters */ -}}
{{- $queryParams := slice -}}
{{- $serviceParams := slice "url" "id" "type" "width" "height" "ratio" "allow" "title" -}}
{{- range $key, $value := .Params -}}
  {{- if and (ne $key "_") (not (in $serviceParams $key)) -}}
    {{- $encodedValue := $value | urlquery -}}
    {{- $queryParams = $queryParams | append (printf "%s=%s" $key $encodedValue) -}}
  {{- end -}}
{{- end -}}

{{- if gt (len $queryParams) 0 -}}
  {{- $queryString := delimit $queryParams "&" -}}
  {{- $embedUrl = printf "%s?%s" $embedUrl $queryString -}}
{{- end -}}

{{- /* Determine mode: responsive or fixed */ -}}
{{- $isFixed := and $width $height -}}

{{- if $isFixed -}}
  <div class="kinescope-embed kinescope-embed-fixed">
    <iframe 
      src="{{ $embedUrl }}"
      allow="{{ $allow }}"
      frameborder="0"
      allowfullscreen
      width="{{ $width }}"
      height="{{ $height }}"
      loading="lazy">
    </iframe>
  </div>
{{- else -}}
  <div class="kinescope-embed kinescope-embed-responsive" style="position: relative; padding-top: {{ $ratio }}%; width: 100%;">
    <iframe 
      src="{{ $embedUrl }}"
      allow="{{ $allow }}"
      frameborder="0"
      allowfullscreen
      style="position: absolute; width: 100%; height: 100%; top: 0; left: 0;"
      loading="lazy">
    </iframe>
  </div>
{{- end -}}
```

## **Setup: step 2 — add CSS styles**

Add CSS styles for correct display (optional, if they're not in your theme):

```css
/* Kinescope embed styles */
.kinescope-embed {
    margin: 1.5em 0;
    border-radius: var(--radius-md);
    overflow: hidden;
    background: var(--color-bg-tertiary);
}

.kinescope-embed-responsive {
    position: relative;
    width: 100%;
}

.kinescope-embed-responsive iframe {
    position: absolute;
    width: 100%;
    height: 100%;
    top: 0;
    left: 0;
    border: none;
}

.kinescope-embed-fixed {
    display: inline-block;
    max-width: 100%;
}

.kinescope-embed-fixed iframe {
    display: block;
    border: none;
    max-width: 100%;
    height: auto;
}
```

## **Using the shortcode**

### **Basic video embedding**

The simplest approach — specify the full video URL:

```markdown
{{</* kinescope url="https://kinescope.io/pcFNnQGsD59CMKte2SQQaz" */>}}
```

Or use just the video ID:

```markdown
{{</* kinescope id="pcFNnQGsD59CMKte2SQQaz" */>}}
```

Video embedding example:

[Видео Kinescope]

### **Embedding playlists**

For playlists, use the URL with the `/pl/` prefix:

```markdown
{{</* kinescope url="https://kinescope.io/pl/5ifZjJLLGYncrHYBdPNhKE" */>}}
```

Or specify the type and ID:

```markdown
{{</* kinescope type="pl" id="5ifZjJLLGYncrHYBdPNhKE" */>}}
```

Playlist embedding example:

[Видео Kinescope]

### **Fixed player size**

By default, the player is responsive and adapts to the container width. For a fixed size, specify `width` and `height`:

```markdown
{{</* kinescope id="pcFNnQGsD59CMKte2SQQaz" width="560" height="315" */>}}
```

### **Playback parameters**

The shortcode supports passing parameters via query string. For example, to play a video segment:

```markdown
{{</* kinescope url="https://kinescope.io/pcFNnQGsD59CMKte2SQQaz" seek="60" duration="30" */>}}
```

This example starts the video from the 60th second and plays only the next 30 seconds.

Example with parameters:

[Видео Kinescope]

### **Using different player templates**

To apply a specific player template, use the `player_id` parameter:

```markdown
{{</* kinescope id="9cdAfqbbPcwu9GJwyxZ6jA" player_id="1213d24d-4624-4764-bf40-0baaf743377d" */>}}
```

### **Setting the aspect ratio**

For non-standard video formats, you can change the aspect ratio (default is 16:9, corresponding to `padding-top: 56.25%`):

```markdown
{{</* kinescope id="..." ratio="75" */>}}
```

The `ratio` value is specified as a percentage. For example:
* `56.25` — standard 16:9 ratio
* `75` — 4:3 ratio
* `100` — square 1:1 video

## **Usage examples in content**

### **In documentation**

Add video to a documentation article:

```markdown
## Setting up the integration

To get started with the integration, watch the tutorial video:

{{</* kinescope url="https://kinescope.io/pcFNnQGsD59CMKte2SQQaz" */>}}

After watching the video, move on to the next step...
```

### **In a blog**

Embed video in blog posts:

```markdown
---
title: "New Kinescope Feature"
date: 2025-12-25
---

The video below showcases the new platform feature. Watch the demo:

{{</* kinescope id="pcFNnQGsD59CMKte2SQQaz" */>}}

After the video, add a short description and a link to the detailed article if needed.
```

### **In online courses**

Use playlists for sequential learning:

```markdown
## Lesson 1: Getting Started

Watch all videos in the playlist:

{{</* kinescope url="https://kinescope.io/pl/iUsqhEMVWJCcUqg9Ay9gmD" */>}}
```

## **How it works (in detail)**

### **Validation and error handling**

The shortcode automatically checks parameter correctness during site build:

* If neither `url` nor `id` is specified, Hugo will return an error during build
* If the URL has an unsupported format, the build will fail with an error
* All errors are shown in the console when running `hugo` or `hugo server`

Example error for incorrect usage:

```bash
ERROR: kinescope shortcode: either 'url' or 'id' parameter is required
```

### **What the integration provides**

* **Uniform embedding**: videos and playlists are embedded the same way — via shortcode.
* **Responsive**: the player adapts to the container width.
* **Parameters**: playback settings can be passed (`seek`, `duration`, `player_id`, etc.).
* **Build-time checks**: parameter errors are visible immediately during site build.
* **Lazy loading**: the iframe loads lazily to avoid overloading the page.

### **Lazy loading**

All iframes automatically load with the `loading="lazy"` attribute, improving page performance.

### **Support for all Kinescope parameters**

The shortcode supports all parameters that can be passed in the player URL:
* `seek` — initial playback position (in seconds)
* `duration` — segment duration (in seconds)
* `player_id` — player template ID
* `autoplay` — video autoplay
* And other Kinescope API parameters

Simply add them as shortcode parameters:

```markdown
{{</* kinescope id="..." seek="60" duration="30" autoplay="1" */>}}
```

## **Compatibility**

The shortcode works with:
* Hugo version 0.100.0 and above
* Any Hugo themes
* Markdown and HTML content
* Goldmark and Blackfriday renderers (when `unsafe = true` is enabled in the config)

> **Информация:**

For the shortcode to work, enable the following in `config.toml`:
```toml
[markup]
  [markup.goldmark]
    [markup.goldmark.renderer]
      unsafe = true
```

This allows Hugo to process the HTML code generated by the shortcode.



## **Support**

If you have questions about the Hugo integration or using the shortcode, contact the support chat within the Kinescope interface — specialists will help you set up video embedding in your documentation or blog.

Hugo documentation is available on the [official website](https://gohugo.io/documentation/).

That's it! You can now embed Kinescope videos and playlists in your Hugo documentation or blog.

## What's next?

After setting up the Hugo integration, we recommend:

1. **[Embedding](https://docs.kinescope.com/video-player/embedding/)** — general principles of video embedding
2. **[Customize the player](https://docs.kinescope.com/video-player/player-customization/)** — adapt the player's appearance to your brand
3. **[Set up content protection](https://docs.kinescope.com/content-protection/)** — enable DRM encryption and watermarks to protect video
4. **[Restrict access by domain](https://docs.kinescope.com/content-protection/access-restrictions/)** — allow video viewing only on your site

If you have any questions, write to the support chat within the Kinescope interface — our specialists will help!

