-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathblog-thumbnail.tsx
More file actions
46 lines (38 loc) · 2.15 KB
/
Copy pathblog-thumbnail.tsx
File metadata and controls
46 lines (38 loc) · 2.15 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import 'server-only';
import path from 'node:path/posix';
import { hasProtocol } from 'ufo';
import Image from 'next/image';
import type { StaticImport } from 'next/dist/shared/lib/get-img-props';
export type BlogThumbnailProps = Omit<React.ComponentProps<typeof Image>, 'src'> & {
src: string
};
export default async function BlogThumbnail({ src, alt, placeholder, ...restProps }: BlogThumbnailProps) {
// Only images under public/blog/cover can be statically imported (and blurred);
// anything else (remote URLs, generated /og/blog images) is passed through as-is.
if (hasProtocol(src) || !src.startsWith('/blog/cover/')) {
if (placeholder === 'blur') {
// eslint-disable-next-line @eslint-react/purity -- We are doing static export, and this warning is emitted during build time
process.emitWarning(`[BlogThumbnail] blur placeholder is only supported for images under public/blog/cover, ignoring: ${src}`);
placeholder = undefined;
}
return <Image src={src} alt={alt} placeholder={placeholder} {...restProps} />;
}
// The static prefix '../../../../../public/' or '@public/' is a compile-time constant so Turbopack
// can build a module context for the directory.
//
// The dynamic bit is calculated dynamically from front-matter at server runtime, computed
// via path.relative for portability.
//
// due to the limitation of template literal import (whatever bundler), bundler can't static
// analyze and tree shake usage, thus can only import everything under the folder.
//
// By limiting the scope to `public/blog/cover` we can avoid importing unnecessary files.
const srcRelativeToCoverDir = path.relative('/blog/cover', src);
let imgData = await import(`@public/blog/cover/${srcRelativeToCoverDir}`) as StaticImport;
// interop default. this is to workaround the following warning:
// > Only plain objects can be passed to Client Components from Server Components. Module objects are not supported.
if ('default' in imgData && typeof imgData.default === 'object' && 'src' in imgData.default) {
imgData = imgData.default;
}
return <Image src={imgData} alt={alt} placeholder={placeholder} {...restProps} />;
}