我正在 Next.js 14 项目中构建一个推荐功能,其中使用 iframe 嵌入推荐。我的目标是生成一个 iframe 标记(以及可能必要的脚本标记),将其粘贴到任何网站的 HTML 中时,将允许用户查看我们网站上提供的所有推荐。为了处理 iframe 大小调整,我使用推荐的 iframe-resizer 库 - text。
我将 iframe-resizer 包添加到我的项目中,并且由于我的项目是开源的,所以我还包含了所需的 GPL V3 许可证。您可以在这里查看源代码。
但是,我在控制台中遇到了几个问题:
警告:GPLV3 许可证版本 控制台显示有关 GPL V3 许可证的警告: 控制台错误 我已经将 LICENSE 文件添加到我的 GitHub 存储库中,所以我不确定为什么它仍然出现。 这似乎表明 iframe 没有正确响应。我不确定子包是否未正确加载,或者是否有其他原因导致此问题。
这是我正在使用的代码: 嵌入式推荐.tsx:
'use client';
import { Testimonial } from '@/interfaces/Testimonial';
import { FaRegStar, FaStar } from 'react-icons/fa';
import dynamic from 'next/dynamic';
import { useEffect, useState } from 'react';
import './embed.css';
const IframeResizer = dynamic(() => import('@iframe-resizer/react'), { ssr: false });
interface EmbeddedTestimonialsProps {
error: string | null;
testimonials: Testimonial[];
spaceName: string;
}
export default function EmbeddedTestimonials({ error, testimonials, spaceName }: EmbeddedTestimonialsProps) {
const [isClient, setIsClient] = useState(false);
useEffect(() => {
setIsClient(true);
}, []);
const renderStars = (rating: number) => {
return Array.from({ length: 5 }, (_, index) => (
index < rating ? <FaStar key={index} className="text-yellow-500 inline" /> : <FaRegStar key={index} className="text-yellow-500 inline" />
));
};
const content = (
<>
{error && <p className="error">Error: {error}</p>}
{testimonials.length === 0 && !error && <p>No testimonials found for this space.</p>}
<div id="testimonials-container">
{testimonials.map((testimonial: Testimonial) => (
<div key={testimonial.id} className="testimonial">
<div className="testimonial-header">
<div className="testimonial-avatar">
{testimonial.userName.charAt(0).toUpperCase()}
</div>
<div className="testimonial-author">{testimonial.userName}</div>
</div>
<div className="text-yellow-500 mb-2">{renderStars(testimonial.rating)}</div>
<div className="testimonial-content">{testimonial.textContent}</div>
<div className="testimonial-date">{testimonial.createdAt}</div>
</div>
))}
</div>
</>
);
if (!isClient) {
return content;
}
return (
<IframeResizer
license='GPLv3'
checkOrigin={false}
onResized={(event) => {
console.log(`Iframe resized to ${event.height}px height and ${event.width}px width`);
}}
scrolling={false}
style={{ width: '1px', minWidth: '100%' }}
>
{content}
</IframeResizer>
);
}
page.tsx:
import { getTestimonials } from '../../../utils/testimonials';
import { Testimonial } from '@/interfaces/Testimonial';
import EmbeddedTestimonials from './EmbeddedTestimonials';
export const dynamic = 'force-dynamic';
export default async function EmbedPage({ params, searchParams }: {
params: { spaceName: string },
searchParams: { theme?: string, initialCount?: string }
}) {
const { spaceName } = params;
const { theme = 'light', initialCount = '20' } = searchParams;
let testimonials: Testimonial[] = [];
let error = null;
try {
testimonials = await getTestimonials(spaceName) as Testimonial[];
testimonials = testimonials.filter(testimonial => testimonial.isLiked);
} catch (err) {
console.error('Error fetching testimonials:', err);
error = err instanceof Error ? err.message : 'An unknown error occurred';
}
const displayCount = Math.min(parseInt(initialCount), testimonials.length);
return (
<html lang="en">
<head>
<meta charSet="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>{`Wall of Fame - ${spaceName}`}</title>
</head>
<body className={theme === 'light' ? 'light-theme' : 'dark-theme'}>
<EmbeddedTestimonials
error={error}
testimonials={testimonials.slice(0, displayCount)}
spaceName={spaceName}
/>
</body>
</html>
);
}
我尝试过的: 我在这里遵循了 iframe-resizer 的官方 React 集成指南。 我确保 license='GPLv3' 作为道具传递给 IframeResizer 组件。 我已将 @iframe-resizer/child 包添加到项目中。 目标: 目标是生成一个 iframe 标签以及任何所需的脚本标签,以便当此代码嵌入到外部网站的 HTML 中时,它会显示我们网站上可用的所有推荐,并动态调整自身大小以正确适应内容。
其他背景: 该存储库是开源的,并包含 GPL V3 的相应许可证文件。 您可以查看代码text。 任何解决这些错误的帮助将不胜感激!我特别不确定如何解决“iFrame 无响应”问题。
如果您的项目是在 GPL 下发布的,您可以忽略此消息。它对库的运行方式没有影响。