Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 8 additions & 8 deletions src/components/Hero.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -162,13 +162,13 @@ const Hero = () => {
variants={containerVariants}
>
<motion.div variants={itemVariants} className="mb-6 flex justify-center">
<Link
to="/resources?tab=creator-packs"
<a
href="https://osmiumchecks.vercel.app/"
className="inline-flex items-center rounded-full border border-cow-purple/30 bg-cow-purple/10 px-4 py-1.5 text-sm font-medium text-cow-purple transition-colors hover:bg-cow-purple/20 font-geist"
>
<span className="mr-2 px-2 py-0.5 rounded-full bg-cow-purple text-white text-xs font-bold">NEW</span>
Creator Packs are here! <IconArrowRight className="ml-2 h-4 w-4" />
</Link>
Osmium out <IconArrowRight className="ml-2 h-4 w-4" />
</a>
Comment on lines +165 to +171
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Missing target="_blank" and rel="noopener noreferrer" on external links

All three external <a> tags added in this PR are missing target="_blank" and rel="noopener noreferrer". Without target="_blank", clicking any of these links will navigate the user away from the SPA entirely, which is almost certainly unintended. Without rel="noopener noreferrer", the opened external page gets access to window.opener and can perform a reverse-tabnabbing redirect on the originating page.

This same issue applies to:

  • src/components/Hero.tsx line 165 (announcement badge)
  • src/components/Hero.tsx line 229 (Check Music Copyright CTA)
  • src/components/PopularTools.tsx line 144 (Osmium tool card link)
Suggested change
<a
href="https://osmiumchecks.vercel.app/"
className="inline-flex items-center rounded-full border border-cow-purple/30 bg-cow-purple/10 px-4 py-1.5 text-sm font-medium text-cow-purple transition-colors hover:bg-cow-purple/20 font-geist"
>
<span className="mr-2 px-2 py-0.5 rounded-full bg-cow-purple text-white text-xs font-bold">NEW</span>
Creator Packs are here! <IconArrowRight className="ml-2 h-4 w-4" />
</Link>
Osmium out <IconArrowRight className="ml-2 h-4 w-4" />
</a>
<a
href="https://osmiumchecks.vercel.app/"
target="_blank"
rel="noopener noreferrer"
className="inline-flex items-center rounded-full border border-cow-purple/30 bg-cow-purple/10 px-4 py-1.5 text-sm font-medium text-cow-purple transition-colors hover:bg-cow-purple/20 font-geist"
>

</motion.div>

<motion.h1
Expand Down Expand Up @@ -226,8 +226,8 @@ const Hero = () => {
}}
whileTap={{ scale: 0.95 }}
>
<Link
to="/gappa"
<a
href="https://osmiumchecks.vercel.app/"
className="pixel-btn-secondary inline-flex items-center gap-2 px-6 py-3 text-sm transition-transform"
>
<motion.span
Expand All @@ -237,7 +237,7 @@ const Hero = () => {
<IconMusic className="w-4 h-4" />
</motion.span>
Check Music Copyright
</Link>
</a>
</motion.div>
</motion.div>

Expand All @@ -256,4 +256,4 @@ const Hero = () => {
)
}

export default React.memo(Hero)
export default React.memo(Hero)
107 changes: 62 additions & 45 deletions src/components/PopularTools.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@ const PopularTools = () => {
const tools: Tool[] = [
{
id: 1,
title: 'Music Copyright Checker',
description: 'Check if a song is copyrighted before using it in your videos.',
title: 'Osmium',
description: 'Osmium will be the first and the last tool for your copyright checks.',
icon: IconMusic,
path: '/gappa',
path: 'https://osmiumchecks.vercel.app/',
color: 'from-blue-500/80 to-blue-600/80'
},
{
Expand Down Expand Up @@ -97,57 +97,74 @@ const PopularTools = () => {
whileInView="visible"
viewport={{ once: true }}
>
{tools.map((tool) => (
{tools.map((tool) => {
const isExternal = tool.path.startsWith('http');
const card = (
<div
className={cn(
"h-full pixel-corners flex flex-col p-6 bg-gradient-to-br border-2",
tool.color,
"border-white/10 text-white transition-all duration-300",
hoveredId === tool.id ? "border-white/30 shadow-lg scale-[1.02]" : ""
)}
>
<motion.div
className="p-3 bg-white/10 rounded-md w-fit mb-4"
whileHover={{ rotate: [0, -10, 10, -5, 5, 0] }}
transition={{ duration: 0.5 }}
>
<tool.icon className="h-6 w-6" />
</motion.div>

<h3 className="text-xl font-vt323 mb-2">{tool.title}</h3>

<p className="text-white/70 text-sm flex-grow">
{tool.description}
</p>

<motion.div
className={cn(
"mt-4 text-sm font-semibold",
"transition-transform duration-300",
hoveredId === tool.id ? "translate-x-2" : ""
)}
whileHover={{ x: 5 }}
>
Try it now
</motion.div>
</div>
);

return (
<motion.div
key={tool.id}
variants={itemVariants}
>
<Link
to={tool.path}
className="block"
onMouseEnter={() => setHoveredId(tool.id)}
onMouseLeave={() => setHoveredId(null)}
>
<div
className={cn(
"h-full pixel-corners flex flex-col p-6 bg-gradient-to-br border-2",
tool.color,
"border-white/10 text-white transition-all duration-300",
hoveredId === tool.id ? "border-white/30 shadow-lg scale-[1.02]" : ""
)}
{isExternal ? (
<a
href={tool.path}
className="block"
onMouseEnter={() => setHoveredId(tool.id)}
onMouseLeave={() => setHoveredId(null)}
>
{card}
</a>
) : (
<Link
to={tool.path}
className="block"
onMouseEnter={() => setHoveredId(tool.id)}
onMouseLeave={() => setHoveredId(null)}
>
<motion.div
className="p-3 bg-white/10 rounded-md w-fit mb-4"
whileHover={{ rotate: [0, -10, 10, -5, 5, 0] }}
transition={{ duration: 0.5 }}
>
<tool.icon className="h-6 w-6" />
</motion.div>

<h3 className="text-xl font-vt323 mb-2">{tool.title}</h3>

<p className="text-white/70 text-sm flex-grow">
{tool.description}
</p>

<motion.div
className={cn(
"mt-4 text-sm font-semibold",
"transition-transform duration-300",
hoveredId === tool.id ? "translate-x-2" : ""
)}
whileHover={{ x: 5 }}
>
Try it now
</motion.div>
</div>
</Link>
{card}
</Link>
)}
</motion.div>
))}
)})}
</motion.div>
</div>
</section>
);
};

export default React.memo(PopularTools);
export default React.memo(PopularTools);