Skip to content

Commit 18b741e

Browse files
authored
docs: add a demo video to the Logto MCP Server page (#1482)
1 parent f28d430 commit 18b741e

5 files changed

Lines changed: 140 additions & 1 deletion

File tree

docs/logto-cloud/logto-mcp-server.mdx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ Logto MCP Server is a remote [MCP (Model Context Protocol)](https://modelcontext
1515
Logto MCP Server is built with Logto and [MCP Auth](https://mcp-auth.dev). If you want to build your own remote MCP server, see [Build your own remote MCP server](#build-your-own-remote-mcp-server).
1616
:::
1717

18+
<YouTubeVideo
19+
id="cpjf9b6qt6U"
20+
title="Ship user authentication with one prompt: introducing Logto MCP Server"
21+
/>
22+
1823
## What you can do \{#what-you-can-do}
1924

2025
- **Add authentication to your project**: The AI detects your framework, creates a Logto application, and generates working integration code. Supports 38+ frameworks including React, Next.js, Vue, Nuxt, SvelteKit, Express, Go, Python, iOS, Android, Flutter, and more.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
.video {
2+
position: relative;
3+
width: 100%;
4+
max-width: 560px;
5+
aspect-ratio: 16 / 9;
6+
margin-block: 24px;
7+
margin-inline: auto;
8+
border-radius: 12px;
9+
overflow: hidden;
10+
background: var(--logto-container-neutral-bg);
11+
12+
.player,
13+
.preview {
14+
position: absolute;
15+
inset: 0;
16+
width: 100%;
17+
height: 100%;
18+
border: none;
19+
}
20+
21+
.preview {
22+
display: flex;
23+
align-items: center;
24+
justify-content: center;
25+
padding: 0;
26+
background: none;
27+
cursor: pointer;
28+
29+
.thumbnail {
30+
position: absolute;
31+
inset: 0;
32+
width: 100%;
33+
height: 100%;
34+
object-fit: cover;
35+
}
36+
37+
// Keep the play icon readable regardless of how bright the thumbnail is.
38+
&::after {
39+
content: '';
40+
position: absolute;
41+
inset: 0;
42+
background: rgba(0, 0, 0, 20%);
43+
transition: background 0.2s ease-in-out;
44+
}
45+
46+
&:hover::after,
47+
&:focus-visible::after {
48+
background: rgba(0, 0, 0, 8%);
49+
}
50+
51+
.playIcon {
52+
position: relative;
53+
z-index: 1;
54+
width: 64px;
55+
height: 64px;
56+
color: #fff;
57+
filter: drop-shadow(0 2px 12px rgba(0, 0, 0, 50%));
58+
transition: transform 0.2s ease-in-out;
59+
60+
@media (max-width: 480px) {
61+
width: 48px;
62+
height: 48px;
63+
}
64+
}
65+
66+
&:hover .playIcon,
67+
&:focus-visible .playIcon {
68+
transform: scale(1.08);
69+
}
70+
}
71+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
import { translate } from '@docusaurus/Translate';
2+
import { useState } from 'react';
3+
4+
import PlayIcon from '@site/src/assets/video.svg';
5+
6+
import styles from './index.module.scss';
7+
8+
type Props = {
9+
/** The YouTube video ID, e.g. `cpjf9b6qt6U` of `https://www.youtube.com/watch?v=cpjf9b6qt6U`. */
10+
readonly id: string;
11+
/** The video title. It is used as the accessible name of the video. */
12+
readonly title: string;
13+
};
14+
15+
/**
16+
* An embedded YouTube video.
17+
*
18+
* Only the thumbnail is rendered at first, and the YouTube player is loaded after the user clicks
19+
* play, so pages with a video don't pay the cost of the player (and its cookies) on every visit.
20+
*/
21+
const YouTubeVideo = ({ id, title }: Props) => {
22+
const [isPlaying, setIsPlaying] = useState(false);
23+
24+
return (
25+
<div className={styles.video}>
26+
{isPlaying ? (
27+
// The YouTube player needs both scripts and its own origin to work, which sandboxing
28+
// cannot express; the frame is cross-origin and cannot touch this page anyway.
29+
// eslint-disable-next-line react/iframe-missing-sandbox
30+
<iframe
31+
allowFullScreen
32+
className={styles.player}
33+
src={`https://www.youtube-nocookie.com/embed/${id}?autoplay=1`}
34+
title={title}
35+
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
36+
/>
37+
) : (
38+
<button
39+
type="button"
40+
className={styles.preview}
41+
aria-label={translate(
42+
{ id: 'component.youTubeVideo.play', message: 'Play video: {title}' },
43+
{ title }
44+
)}
45+
onClick={() => {
46+
setIsPlaying(true);
47+
}}
48+
>
49+
<img
50+
alt=""
51+
className={styles.thumbnail}
52+
src={`https://i.ytimg.com/vi/${id}/maxresdefault.jpg`}
53+
/>
54+
<PlayIcon className={styles.playIcon} />
55+
</button>
56+
)}
57+
</div>
58+
);
59+
};
60+
61+
export default YouTubeVideo;

src/theme/MDXComponents/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import CloudLink from '@site/src/components/CloudLink';
44
import MainSiteUrl from '@site/src/components/MainSiteUrl';
55
import NavGroup from '@site/src/components/NavGroup';
66
import Url from '@site/src/components/Url';
7+
import YouTubeVideo from '@site/src/components/YouTubeVideo';
78

89
import DocCardList from '../DocCardList';
910

@@ -16,6 +17,7 @@ const components = {
1617
NavGroup,
1718
Url,
1819
MainSiteUrl,
20+
YouTubeVideo,
1921
table: Table,
2022
};
2123

static/_headers

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
/*
2-
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://akasha.logto.io https://accounts.google.com; connect-src 'self' https://akasha.logto.io https://accounts.google.com https://auth.logto.dev https://*.logto.dev https://auth.logto.io https://*.logto.io https://api.inkeep.com; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://accounts.google.com https://fonts.googleapis.com; font-src 'self' https://cdn.jsdelivr.net https://fonts.gstatic.com; frame-src https://accounts.google.com; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; form-action 'self' https://*.logto.dev https://*.logto.io https://cloud.logto.dev https://cloud.logto.io
2+
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' https://akasha.logto.io https://accounts.google.com; connect-src 'self' https://akasha.logto.io https://accounts.google.com https://auth.logto.dev https://*.logto.dev https://auth.logto.io https://*.logto.io https://api.inkeep.com; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net https://accounts.google.com https://fonts.googleapis.com; font-src 'self' https://cdn.jsdelivr.net https://fonts.gstatic.com; frame-src https://accounts.google.com https://www.youtube-nocookie.com https://www.youtube.com; img-src 'self' data: https:; object-src 'none'; base-uri 'self'; form-action 'self' https://*.logto.dev https://*.logto.io https://cloud.logto.dev https://cloud.logto.io

0 commit comments

Comments
 (0)