๐Ÿ”— 05. a ํƒœ๊ทธ ๊นŠ๊ฒŒ ํŒŒ๊ธฐ: href='#' ๋Š” ์ด์ œ ๋ฒ„๋ฆฌ์ž

2026๋…„ 3์›” 5์ผ ์ˆ˜์ •๋จ

๐Ÿ“‹ ๊ฐœ์š”

href, target, rel, download, tel:/mailto: โ€” ์•ต์ปค ํƒœ๊ทธ์˜ ๋ชจ๋“  ์†์„ฑ๊ณผ ๋ณด์•ˆ ํ•จ์ •, Next.js Link ์ปดํฌ๋„ŒํŠธ์™€์˜ ์ฐจ์ด๋ฅผ ํŒŒํ—ค์นฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์ด ๋ฌธ์„œ๋ฅผ ์ฝ๊ธฐ ์ „์—

โฑ๏ธ ์˜ˆ์ƒ ์ฝ๊ธฐ ์‹œ๊ฐ„: 15๋ถ„ / ํ•ต์‹ฌ ํŒŒํŠธ๋งŒ: 8๋ถ„

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ํ๋ฆ„

[a ํƒœ๊ทธ์˜ ์ง„์งœ ์—ญํ• ] โ†’ [href ์™„์ „ ํ•ด๋ถ€] โ†’ [target + rel ๋ณด์•ˆ] โ†’ [Next.js Link vs a] โ†’ [๋งํฌ ์ ‘๊ทผ์„ฑ]

๐ŸŽฏ ์ด ๋ฌธ์„œ๋ฅผ ๋‹ค ์ฝ์œผ๋ฉด ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ

  • href ์— ๋“ค์–ด๊ฐˆ ์ˆ˜ ์žˆ๋Š” URL ์Šคํ‚ด ์ข…๋ฅ˜๋ฅผ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • target="_blank" ์™€ rel="noopener noreferrer" ๋ฅผ ์™œ ํ•จ๊ป˜ ์จ์•ผ ํ•˜๋Š”์ง€ ๋ณด์•ˆ ์›๋ฆฌ๋กœ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค.
  • <a href="#"> ๋Œ€์‹  <button> ์„ ์“ธ ํŒ๋‹จ ๊ธฐ์ค€์„ ๊ฐ–๋Š”๋‹ค.
  • Next.js <Link> ์™€ HTML <a> ์˜ ์ฐจ์ด๋ฅผ ์•ˆ๋‹ค.

๐Ÿ—บ๏ธ ์ด ๋ฌธ์„œ์˜ ๋ฐฐ๊ฒฝ ์„ธ๊ณ„๊ด€: '์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ'

  • ๐Ÿฃ ์˜์ฒ  ( ์‹ ์ž… ): "์˜ํ˜ธ ๋‹˜, ์ € ๋ฒ„ํŠผ์ฒ˜๋Ÿผ ์ƒ๊ธด ๋งํฌ ๋งŒ๋“ค๊ณ  ์‹ถ์–ด์„œ <a href='#'> ์— onClick ๋‹ฌ์•˜์–ด์š”. ๊ทธ๋ฆฌ๊ณ  ์™ธ๋ถ€ ๋งํฌ๋Š” ์ƒˆ ํƒญ์—์„œ ์—ด๋ฆฌ๊ฒŒ target='_blank' ๋„ฃ์—ˆ๋Š”๋ฐ ์ด๊ฑฐ๋ฉด ๋˜๋Š” ๊ฑฐ ์•„๋‹Œ๊ฐ€์š”?"
  • ๐Ÿฆ ์˜ํ˜ธ ( ๋ฆฌ๋“œ ): "๋‘ ๊ฐ€์ง€ ๋‹ค ๊ณ ์ณ์•ผ ํ•ด์š”. href='#' ์€ URL์„ # ์œผ๋กœ ๋ฐ”๊พธ๋Š” ๋ถ€์ž‘์šฉ์ด ์žˆ๊ณ , ์ง„์งœ ๋„ค๋น„๊ฒŒ์ด์…˜ ๊ธฐ๋Šฅ ์—†๋Š” ๊ฑฐ๋ฉด <button> ์ด ๋งž์•„์š”. ๊ทธ๋ฆฌ๊ณ  target='_blank' ์— rel='noopener' ์—†์œผ๋ฉด ๋ณด์•ˆ ๊ตฌ๋ฉ์ด ์ƒ๊ธธ ์ˆ˜ ์žˆ์–ด์š”."

๐Ÿค” ์™œ ์•Œ์•„์•ผ ํ•˜๋Š”๊ฐ€

์˜์ˆ˜๋„ค ์ปค๋ฎค๋‹ˆํ‹ฐ ๋ณด์•ˆ ๊ฐ์‚ฌ์—์„œ ์™ธ๋ถ€ ๋งํฌ ํŽ˜์ด์ง€์— ๊ฒฝ๊ณ ๊ฐ€ ๋–ด๋‹ค.

๐Ÿฆ ์˜ํ˜ธ ๋ฆฌ๋“œ: "์˜์ฒ  ๋‹˜, ์™ธ๋ถ€ ๋งํฌ ์ „๋ถ€ rel='noopener noreferrer' ๋น ์ ธ์žˆ์–ด์š”. target='_blank' ๋กœ ์—ด๋ฆฌ๋Š” ํƒญ์ด window.opener ๋กœ ์šฐ๋ฆฌ ์›๋ณธ ํƒญ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์š”. ์•…์„ฑ ์‚ฌ์ดํŠธ๊ฐ€ ๋งํฌ๋ฅผ ํƒ€๊ณ  ์šฐ๋ฆฌ ์„œ๋น„์Šค URL์„ ํ”ผ์‹ฑ ํŽ˜์ด์ง€๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค."

<!-- โŒ ์˜์ฒ ์ด์˜ ์œ„ํ—˜ํ•œ ์™ธ๋ถ€ ๋งํฌ -->
<a href="https://external-site.com" target="_blank">์™ธ๋ถ€ ๋งํฌ</a>
<!-- ์ด ์ƒˆ ํƒญ์—์„œ window.opener.location = 'https://phishing-site.com' ๊ฐ€๋Šฅ! -->

๐Ÿ”— 1. href โ€” ๋งํฌ๊ฐ€ ๊ฐˆ ์ˆ˜ ์žˆ๋Š” ๋ชจ๋“  ๊ณณ

<a> ๋Š” URL ํ˜•์‹์ด๋ผ๋ฉด ๊ฑฐ์˜ ๋ชจ๋“  ๊ฒƒ์„ ๋งํฌ๋กœ ๋งŒ๋“ค ์ˆ˜ ์žˆ์–ด.

<!-- ์ผ๋ฐ˜ URL -->
<a href="https://example.com">์™ธ๋ถ€ ์‚ฌ์ดํŠธ</a>
<a href="/posts">๋‚ด๋ถ€ ํŽ˜์ด์ง€ (์ ˆ๋Œ€ ๊ฒฝ๋กœ)</a>
<a href="./about">ํ˜„์žฌ ๋””๋ ‰ํ† ๋ฆฌ ๊ธฐ์ค€ (์ƒ๋Œ€ ๊ฒฝ๋กœ)</a>
 
<!-- ํŽ˜์ด์ง€ ๋‚ด ํŠน์ • ์„น์…˜์œผ๋กœ ์ด๋™ (Fragment Identifier) -->
<a href="#section-2">์„น์…˜ 2๋กœ ์ด๋™</a>
<!-- ์ด๋™ ๋Œ€์ƒ ์š”์†Œ: <h2 id="section-2">์„น์…˜ 2</h2> -->
 
<!-- ์ด๋ฉ”์ผ ํด๋ผ์ด์–ธํŠธ ์—ด๊ธฐ -->
<a href="mailto:support@ysdeveloper.community">์ด๋ฉ”์ผ ๋ฌธ์˜</a>
<a href="mailto:help@example.com?subject=์ œ๋ชฉ&body=๋‚ด์šฉ">์ œ๋ชฉ ํฌํ•จ ์ด๋ฉ”์ผ</a>
 
<!-- ์ „ํ™” ๊ฑธ๊ธฐ (๋ชจ๋ฐ”์ผ์—์„œ ์ž๋™ ๋‹ค์ด์–ผ) -->
<a href="tel:+82-10-1234-5678">์ „ํ™”ํ•˜๊ธฐ</a>
 
<!-- ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ (๋™์ผ ์ถœ์ฒ˜๋งŒ ์ž‘๋™) -->
<a href="/files/report.pdf" download="2025-์—ฐ๊ฐ„๋ณด๊ณ ์„œ.pdf">PDF ๋‹ค์šด๋กœ๋“œ</a>

๐Ÿšซ javascript:void(0) ์ ˆ๋Œ€ ๊ธˆ์ง€
href="javascript:void(0)" ๋Š” JavaScript๊ฐ€ ๊บผ์ ธ ์žˆ๊ฑฐ๋‚˜ ์˜ค๋ฅ˜๊ฐ€ ๋‚˜๋ฉด ์•„๋ฌด๊ฒƒ๋„ ์•ˆ ๋ผ์š”.
๋ถ๋งˆํฌ, ๋งํฌ ๋ณต์‚ฌ, ์ƒˆ ํƒญ ์—ด๊ธฐ๋„ ์ „๋ถ€ ๋ง๊ฐ€์ ธ์š”. ๋ฒ„ํŠผ์ด ํ•„์š”ํ•˜๋ฉด <button> ์„ ์จ์•ผ ํ•ด์š”.


๐Ÿ›ก๏ธ 2. target + rel โ€” ์ƒˆ ํƒญ ๋ณด์•ˆ์˜ ์ง„์‹ค

2-1. target="_blank" ์™€ window.opener ๋ณด์•ˆ ์ทจ์•ฝ์ 

<!-- โŒ ๊ตฌ๋ฒ„์ „ ๋ธŒ๋ผ์šฐ์ € ๊ธฐ์ค€ ์œ„ํ—˜ํ•œ ํŒจํ„ด -->
<a href="https://external-bad-site.com" target="_blank">์™ธ๋ถ€ ๋งํฌ</a>

target="_blank" ๋กœ ์—ด๋ฆฐ ์ƒˆ ํƒญ์€ window.opener ๋กœ ์›๋ณธ ํƒญ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์—ˆ์–ด (๊ตฌ๋ฒ„์ „ ๋ธŒ๋ผ์šฐ์ €). ์•…์„ฑ ์‚ฌ์ดํŠธ๊ฐ€ ์ด๊ฑธ ์ด์šฉํ•ด์„œ ์›๋ณธ ํƒญ์˜ URL์„ ํ”ผ์‹ฑ ์‚ฌ์ดํŠธ๋กœ ๋ฐ”๊ฟ€ ์ˆ˜ ์žˆ์—ˆ์–ด.

<!-- โœ… ์•ˆ์ „ํ•œ ์™ธ๋ถ€ ๋งํฌ ํŒจํ„ด -->
<a
  href="https://external-site.com"
  target="_blank"
  rel="noopener noreferrer"
>
  ์™ธ๋ถ€ ๋งํฌ (์ƒˆ ํƒญ, ์•ˆ์ „)
</a>
  • rel="noopener": window.opener ๋ฅผ null ๋กœ ์„ค์ • โ†’ ์›๋ณธ ํƒญ ์ ‘๊ทผ ๋ถˆ๊ฐ€
  • rel="noreferrer": Referer HTTP ํ—ค๋”๋ฅผ ๋ณด๋‚ด์ง€ ์•Š์Œ โ†’ ์–ด๋””์„œ ์™”๋Š”์ง€ ์™ธ๋ถ€์— ๋…ธ์ถœ ์•ˆ ๋จ

๐Ÿ”— ์ตœ์‹  ๋ธŒ๋ผ์šฐ์ €์—์„œ๋Š”?
๋ชจ๋˜ ๋ธŒ๋ผ์šฐ์ €(Chrome 88+, Firefox 79+)๋Š” target="_blank" ์— ์•”๋ฌต์ ์œผ๋กœ noopener ๋ฅผ ์ ์šฉํ•ด์ค˜์š”. ํ•˜์ง€๋งŒ ๋ ˆ๊ฑฐ์‹œ ๋ธŒ๋ผ์šฐ์ € ์ง€์›์ด๋‚˜ ๋ช…์‹œ์  ์˜๋„ ์ „๋‹ฌ์„ ์œ„ํ•ด ๋ช…์‹œ์ ์œผ๋กœ rel="noopener noreferrer" ๋ฅผ ์“ฐ๋Š” ๊ฒŒ 5๋…„ ์ฐจ์˜ ์Šต๊ด€์ด์—์š”.

2-2. rel ์†์„ฑ์˜ ๋‹ค๋ฅธ ๊ฐ’๋“ค

<!-- SEO: ์ด ๋งํฌ๋Š” ๊ฒ€์ƒ‰์—”์ง„์ด ๋”ฐ๋ผ๊ฐ€์ง€ ๋ง ๊ฒƒ -->
<a href="https://ads.example.com" rel="nofollow">๊ด‘๊ณ  ๋งํฌ</a>
 
<!-- ์ด์ „/๋‹ค์Œ ํŽ˜์ด์ง€ (SEO ํžŒํŠธ) -->
<a href="/posts?page=2" rel="next">๋‹ค์Œ ํŽ˜์ด์ง€</a>
<a href="/posts?page=1" rel="prev">์ด์ „ ํŽ˜์ด์ง€</a>

๐Ÿ†š 3. <a> vs <button> โ€” ๊ฐ€์žฅ ๋งŽ์ด ํ—ท๊ฐˆ๋ฆฌ๋Š” ์„ ํƒ

๐Ÿฃ ์˜์ฒ : "๊ทธ๋Ÿผ href='#' ์“ฐ๋ฉด ์•ˆ ๋˜๋ฉด ์–ธ์ œ <a> ์“ฐ๊ณ  ์–ธ์ œ <button> ์จ์š”?"

Q. ์ด ์š”์†Œ๋ฅผ ํด๋ฆญํ•˜๋ฉด...
  โ”œโ”€ ๋‹ค๋ฅธ URL/ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š”๊ฐ€?    โ†’ <a href="..."> ์‚ฌ์šฉ
  โ””โ”€ ํ˜„์žฌ ํŽ˜์ด์ง€์—์„œ ๋™์ž‘(toggle, submit, open modal ๋“ฑ)์ธ๊ฐ€?
                                    โ†’ <button> ์‚ฌ์šฉ
<!-- โŒ ์ž˜๋ชป๋œ ํŒจํ„ด: ๋งํฌ์ฒ˜๋Ÿผ ์ƒ๊ธด ๋ฒ„ํŠผ -->
<a href="#" onclick="openModal()">๋ชจ๋‹ฌ ์—ด๊ธฐ</a>
<!-- ํด๋ฆญ ์‹œ URL์ด '#'์œผ๋กœ ๋ฐ”๋€Œ๊ณ , ํŽ˜์ด์ง€ ์ƒ๋‹จ์œผ๋กœ ์ ํ”„ -->
 
<!-- โœ… ์˜ฌ๋ฐ”๋ฅธ ํŒจํ„ด -->
<button type="button" onclick="openModal()">๋ชจ๋‹ฌ ์—ด๊ธฐ</button>
<!-- CSS๋กœ ๋งํฌ์ฒ˜๋Ÿผ ์Šคํƒ€์ผ๋ง ๊ฐ€๋Šฅ, ๊ธฐ๋Šฅ์€ ๋ฒ„ํŠผ -->
 
<!-- โœ… ์˜ฌ๋ฐ”๋ฅธ ๋งํฌ: ์‹ค์ œ ํŽ˜์ด์ง€ ์ด๋™ -->
<a href="/posts/1">๊ฒŒ์‹œ๊ธ€ ๋ณด๊ธฐ</a>

ํ‚ค๋ณด๋“œ ์ ‘๊ทผ์„ฑ ์ฐจ์ด:

  • <a>: Enter ํ‚ค๋กœ ํ™œ์„ฑํ™”, Tab์œผ๋กœ ํฌ์ปค์Šค ์ด๋™
  • <button>: Enter + Space ๋ฐ” ๋‘˜ ๋‹ค ํ™œ์„ฑํ™”, Tab์œผ๋กœ ํฌ์ปค์Šค ์ด๋™

๐Ÿฃ ์˜์ฒ : "Next.js์—์„œ๋Š” <Link> ๋ฅผ ์จ์•ผ ํ•œ๋‹ค๊ณ  ํ•˜๋Š”๋ฐ, <a> ๋ž‘ ๋ญ๊ฐ€ ๋‹ฌ๋ผ์š”?"

import Link from "next/link";
 
// โŒ Next.js์—์„œ <a> ์‚ฌ์šฉ: ํ’€ ํŽ˜์ด์ง€ ๋ฆฌ๋กœ๋“œ ๋ฐœ์ƒ
<a href="/posts">๊ฒŒ์‹œํŒ</a>
 
// โœ… Next.js <Link>: SPA์ฒ˜๋Ÿผ ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋„ค๋น„๊ฒŒ์ด์…˜
// ์ „์ฒด ๋ฆฌ๋กœ๋“œ ์—†์ด ํ•„์š”ํ•œ ์ปดํฌ๋„ŒํŠธ๋งŒ ๊ต์ฒด
<Link href="/posts">๊ฒŒ์‹œํŒ</Link>
 
// Link ์ฃผ์š” props
<Link
  href="/posts/1"
  prefetch={true}       // hover ์‹œ ๋ฏธ๋ฆฌ ๋ฐ์ดํ„ฐ ๋กœ๋“œ (๊ธฐ๋ณธ๊ฐ’)
  replace={false}       // ํžˆ์Šคํ† ๋ฆฌ push ๋Œ€์‹  replace
>
  ๊ฒŒ์‹œ๊ธ€ ๋ณด๊ธฐ
</Link>

Next.js <Link> ๊ฐ€ <a> ๋ณด๋‹ค ๋‚˜์€ ์ด์œ :

  1. Prefetching: ๋ทฐํฌํŠธ์— ๋ณด์ด๋Š” Link ๋ฅผ ๋ฏธ๋ฆฌ ํŒจ์น˜ โ†’ ํด๋ฆญ ์‹œ ์ฆ‰๊ฐ ๋ฐ˜์‘
  2. SPA ๋ฐฉ์‹ ์ด๋™: ๊ณตํ†ต ๋ ˆ์ด์•„์›ƒ(layout.tsx)์€ ์œ ์ง€ํ•˜๊ณ  ๋ณ€๊ฒฝ๋œ ์ปดํฌ๋„ŒํŠธ๋งŒ ๊ต์ฒด
  3. ์Šคํฌ๋กค ๋ณต์›: ๋’ค๋กœ๊ฐ€๊ธฐ ์‹œ ์ด์ „ ์Šคํฌ๋กค ์œ„์น˜ ์ž๋™ ๋ณต์›

๋‹จ, ์™ธ๋ถ€ ๋งํฌ๋Š” Next.js <Link> ๊ฐ€ ์•„๋‹Œ <a target="_blank" rel="noopener noreferrer"> ์‚ฌ์šฉ!


โ™ฟ 5. ๋งํฌ ์ ‘๊ทผ์„ฑ โ€” ๋งํฌ ํ…์ŠคํŠธ๊ฐ€ ์ „๋ถ€๋‹ค

์Šคํฌ๋ฆฐ๋ฆฌ๋”๋Š” ํŽ˜์ด์ง€์˜ ๋ชจ๋“  ๋งํฌ๋ฅผ ๋ชฉ๋ก์œผ๋กœ ์ฝ์–ด์ค˜. ๋งํฌ ํ…์ŠคํŠธ๊ฐ€ ๋งฅ๋ฝ ์—†์ด ๋ถˆ๋ถ„๋ช…ํ•˜๋ฉด ์‚ฌ์šฉ์ž๊ฐ€ ์–ด๋””๋กœ ๊ฐ€๋Š”์ง€ ์•Œ ์ˆ˜ ์—†์–ด.

<!-- โŒ ๋‚˜์œ ๋งํฌ ํ…์ŠคํŠธ: ๋งฅ๋ฝ ์—†์Œ -->
<p>์ž์„ธํ•œ ๋‚ด์šฉ์€ <a href="/posts/1">์—ฌ๊ธฐ๋ฅผ ํด๋ฆญํ•˜์„ธ์š”</a>.</p>
<!-- ์Šคํฌ๋ฆฐ๋ฆฌ๋”: "์—ฌ๊ธฐ๋ฅผ ํด๋ฆญํ•˜์„ธ์š”" โ†’ ์–ด๋””๋กœ ๊ฐ€๋Š”์ง€ ๋ชจ๋ฆ„ -->
 
<!-- โœ… ์ข‹์€ ๋งํฌ ํ…์ŠคํŠธ: ๋ชฉ์ ์ง€๊ฐ€ ๋ช…ํ™•ํ•จ -->
<p>์ž์„ธํ•œ ๋‚ด์šฉ์€ <a href="/posts/1">๋ฆฌ์•กํŠธ ์ƒํƒœ๊ด€๋ฆฌ ๊ฐ€์ด๋“œ</a>๋ฅผ ์ฐธ๊ณ ํ•˜์„ธ์š”.</p>
<!-- ์Šคํฌ๋ฆฐ๋ฆฌ๋”: "๋ฆฌ์•กํŠธ ์ƒํƒœ๊ด€๋ฆฌ ๊ฐ€์ด๋“œ" โ†’ ๋ช…ํ™•ํ•œ ๋ชฉ์ ์ง€ -->
 
<!-- ์•„์ด์ฝ˜๋งŒ ์žˆ๋Š” ๋งํฌ: aria-label ํ•„์ˆ˜ -->
<a href="/settings" aria-label="์„ค์ • ํŽ˜์ด์ง€๋กœ ์ด๋™">
  <svg>...</svg>  {/* ์•„์ด์ฝ˜๋งŒ ์žˆ์œผ๋ฉด ์Šคํฌ๋ฆฐ๋ฆฌ๋”๊ฐ€ ์ฝ์„ ๋‚ด์šฉ์ด ์—†์Œ */}
</a>

๐Ÿ ํ•ต์‹ฌ ํŒจํ„ด ์ด์ •๋ฆฌ

์ƒํ™ฉ์˜ฌ๋ฐ”๋ฅธ ํŒจํ„ด
๋‚ด๋ถ€ ํŽ˜์ด์ง€ ์ด๋™ (Next.js)<Link href="/path">
์™ธ๋ถ€ ๋งํฌ ์ƒˆ ํƒญ ์—ด๊ธฐ<a href="..." target="_blank" rel="noopener noreferrer">
ํด๋ฆญ ๋™์ž‘ (๋ชจ๋‹ฌ, ํ† ๊ธ€)<button type="button">
์ „ํ™” ๋งํฌ<a href="tel:+821012345678">
์ด๋ฉ”์ผ ๋งํฌ<a href="mailto:user@example.com">
ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ<a href="/file.pdf" download="ํŒŒ์ผ๋ช….pdf">
์•„์ด์ฝ˜ ์ „์šฉ ๋งํฌ<a href="..." aria-label="๋ชฉ์ ์ง€ ์„ค๋ช…">


๐Ÿ“ ๋งˆ๋ฌด๋ฆฌ ํ€ด์ฆˆ

Q1. ๋‹ค์Œ ์ค‘ ๋ณด์•ˆ๊ณผ ์ ‘๊ทผ์„ฑ ๋ชจ๋‘๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ตฌํ˜„ํ•œ ์™ธ๋ถ€ ๋งํฌ๋Š”?

  • A) <a href="https://example.com" target="_blank">์™ธ๋ถ€ ๋งํฌ</a>
  • B) <a href="https://example.com" target="_blank" rel="noopener noreferrer">์™ธ๋ถ€ ๋งํฌ (์ƒˆ ํƒญ์—์„œ ์—ด๋ฆผ)</a>
  • ๊ฐ€) <a href="https://example.com" rel="noopener">์™ธ๋ถ€ ๋งํฌ</a>
  • ๋ผ) <a href="javascript:window.open('https://example.com')">์™ธ๋ถ€ ๋งํฌ</a>

โœ… ์ •๋‹ต: B

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: target="_blank" ๋กœ ์ƒˆ ํƒญ์„ ์—ด ๋•Œ rel="noopener" ๊ฐ€ ์—†์œผ๋ฉด ๊ตฌ๋ฒ„์ „ ๋ธŒ๋ผ์šฐ์ €์—์„œ window.opener ๋ฅผ ํ†ตํ•œ ์›๋ณธ ํƒญ ์ ‘๊ทผ์ด ๊ฐ€๋Šฅํ•ด์š”. rel="noreferrer" ๋Š” Referer ํ—ค๋”๋ฅผ ์ฐจ๋‹จํ•ด ๋ฐฉ๋ฌธ ๊ฒฝ๋กœ ๋…ธ์ถœ์„ ๋ง‰์Šต๋‹ˆ๋‹ค. B๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์ƒˆ ํƒญ์—์„œ ์—ด๋ฆฐ๋‹ค๋Š” ํžŒํŠธ๋„ ํ…์ŠคํŠธ๋กœ ์ œ๊ณตํ•ด ์ ‘๊ทผ์„ฑ๋„ ์šฐ์ˆ˜ํ•ด์š”.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "target='_blank' = ๋ฐ˜๋“œ์‹œ rel='noopener noreferrer' ์„ธํŠธ๋กœ"

Q2. ์•„๋ž˜ ์ฝ”๋“œ์˜ ๋ฌธ์ œ์ ๊ณผ ์˜ฌ๋ฐ”๋ฅธ ์ˆ˜์ •๋ฒ•์€?

<a href="#" onclick="toggleMenu()">๋ฉ”๋‰ด ์—ด๊ธฐ</a>

โœ… ์ •๋‹ต: URL์ด # ์œผ๋กœ ๋ฐ”๋€Œ๋Š” ๋ถ€์ž‘์šฉ๊ณผ ์‹œ๋งจํ‹ฑ ๋ฏธ์Šค๋งค์น˜. <button type="button" onclick="toggleMenu()">๋ฉ”๋‰ด ์—ด๊ธฐ</button> ์œผ๋กœ ์ˆ˜์ •

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: <a> ๋Š” "๋„ค๋น„๊ฒŒ์ด์…˜(์ด๋™)์„ ์œ„ํ•œ ์š”์†Œ" ์ž…๋‹ˆ๋‹ค. href="#" ์„ ํด๋ฆญํ•˜๋ฉด ํŽ˜์ด์ง€ URL์ด # ์œผ๋กœ ๋ฐ”๋€Œ๊ณ  ์ƒ๋‹จ์œผ๋กœ ์ ํ”„ํ•˜๋Š” ๋ถ€์ž‘์šฉ์ด ์ƒ๊ฒจ์š”. ๋ฉ”๋‰ด ํ† ๊ธ€์€ ์ด๋™์ด ์•„๋‹Œ "๋™์ž‘(Action)" ์ด๋ฏ€๋กœ <button> ์ด ์‹œ๋งจํ‹ฑ/์ ‘๊ทผ์„ฑ ๋ชจ๋‘ ๋งž์Šต๋‹ˆ๋‹ค.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "์ด๋™ํ•˜๋ฉด <a>, ๋™์ž‘ํ•˜๋ฉด <button>"

Q3. ์˜์ฒ ์ด์˜ ํ…Œ์ŠคํŠธ ํƒ€์ž„

์˜์ฒ ์ด๋Š” Next.js ํ”„๋กœ์ ํŠธ์—์„œ ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ํŽ˜์ด์ง€๋ฅผ ๋งŒ๋“ค์—ˆ๋‹ค.
๊ฐ ๊ฒŒ์‹œ๊ธ€ ์ œ๋ชฉ์„ ํด๋ฆญํ•˜๋ฉด ์ƒ์„ธ ํŽ˜์ด์ง€๋กœ ์ด๋™ํ•˜๋Š” ์ฝ”๋“œ๋ฅผ ์งฐ๋Š”๋ฐ,
์˜ํ˜ธ ๋ฆฌ๋“œ๊ฐ€ "์ด ๋งํฌ๋ฅผ ํด๋ฆญํ•  ๋•Œ๋งˆ๋‹ค ํŽ˜์ด์ง€ ์ „์ฒด๊ฐ€ ์ƒˆ๋กœ๊ณ ์นจ ๋ผ์š”"๋ผ๊ณ  ์ฝ”๋ฉ˜ํŠธ๋ฅผ ๋‚จ๊ฒผ๋‹ค.

์˜์ฒ ์ด๊ฐ€ ์“ด ์ฝ”๋“œ: <a href="/posts/1">๋ฆฌ์•กํŠธ ์ƒํƒœ๊ด€๋ฆฌ ๊ฐ€์ด๋“œ</a>

์–ด๋–ป๊ฒŒ ์ˆ˜์ •ํ•ด์•ผ ํ•˜๊ณ , ์™œ ๊ทธ๋ž˜์•ผ ํ•˜๋Š”๊ฐ€?

โœ… ์ •๋‹ต: import Link from 'next/link' ํ›„ <Link href="/posts/1">๋ฆฌ์•กํŠธ ์ƒํƒœ๊ด€๋ฆฌ ๊ฐ€์ด๋“œ</Link> ๋กœ ์ˆ˜์ •

๐Ÿ’ก ์ƒ์„ธ ํ•ด์„ค:

  • ์›๋ฆฌ ์„ค๋ช…: HTML <a> ๋Š” ํด๋ฆญ ์‹œ ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์ƒˆ HTTP ์š”์ฒญ์„ ๋ณด๋‚ด๊ณ  ์ „์ฒด HTML์„ ๋‹ค์‹œ ๋กœ๋“œํ•ด์š”. Next.js <Link> ๋Š” ํด๋ผ์ด์–ธํŠธ ์‚ฌ์ด๋“œ ๋ผ์šฐํŒ…์œผ๋กœ ํ˜„์žฌ ํŽ˜์ด์ง€์˜ ๊ณตํ†ต ๋ ˆ์ด์•„์›ƒ์€ ๊ทธ๋Œ€๋กœ ๋‘๊ณ , ๋ฐ”๋€ ํŽ˜์ด์ง€ ์ฝ˜ํ…์ธ ๋งŒ ๊ต์ฒดํ•ด์š”. ๋ถˆํ•„์š”ํ•œ ๋ฆฌ์†Œ์Šค ์žฌ๋‹ค์šด๋กœ๋“œ๊ฐ€ ์—†์–ด์„œ ํ›จ์”ฌ ๋น ๋ฅด๊ณ , Prefetch ๋•๋ถ„์— hover ์‹œ ๋ฏธ๋ฆฌ ๋ฐ์ดํ„ฐ๋ฅผ ๋กœ๋“œํ•ด ํด๋ฆญ ์ฆ‰์‹œ ๋ฐ˜์‘ํ•ด์š”.
  • ๐Ÿ“Œ ํ•ต์‹ฌ ๊ธฐ์–ต๋ฒ•: "Next.js ๋‚ด๋ถ€ ๋งํฌ = <Link>, ์™ธ๋ถ€ ๋งํฌ = <a target='_blank' rel='noopener noreferrer'>"

๐Ÿฃ ์˜์ฒ ์ด์˜ ํ‡ด๊ทผ ์ผ๊ธฐ

์˜ค๋Š˜ ์˜ํ˜ธ ๋ฆฌ๋“œ ๋‹˜์ด ๋‚ด PR์—์„œ href='#' ๋‹ฌ๋ฆฐ ๋ถ€๋ถ„์„ ์ „๋ถ€ <button> ์œผ๋กœ ๋ฐ”๊พธ๋ผ๊ณ  ํ–ˆ์„ ๋•Œ ์ฒ˜์Œ์—” ์ข€ ์–ต์šธํ–ˆ๋‹ค. "์–ด์ฐจํ”ผ CSS๋กœ ๋˜‘๊ฐ™์ด ์ƒ๊ธฐ์ž–์•„์š”" ํ–ˆ๋”๋‹ˆ ๋ฆฌ๋“œ ๋‹˜์ด ์ง์ ‘ Tab ํ‚ค๋กœ ์‹œ์—ฐํ•ด์ฃผ์…จ๋‹ค. ์•„ ์ง„์งœ... ํ‚ค๋ณด๋“œ๋กœ ํƒ์ƒ‰ํ•˜๋Š” ์‚ฌ๋žŒ ์ž…์žฅ์—์„œ <a href='#'> ๋Š” '์–ด๋”˜๊ฐ€๋ฅผ ํƒ์ƒ‰ํ•˜๋Š” ๋งํฌ'์ฒ˜๋Ÿผ ๋А๊ปด์ง€๋Š”๋ฐ ๋ฒ„ํŠผ ๋™์ž‘์„ ํ•˜๋‹ˆ๊นŒ ์™„์ „ํžˆ ์‚ฌ์šฉ์ž ๊ธฐ๋Œ€๋ฅผ ๋ฐฐ์‹ ํ•˜๋Š” ๊ฑฐ์˜€๋‹ค.

๐Ÿ’ก "<a> ๋Š” ์–ด๋””๋ก ๊ฐ€ ์ด๋™ํ•  ๋•Œ, <button> ์€ ๋ฌด์–ธ๊ฐ€๋ฅผ ํ•  ๋•Œ. href='#' ์— onClick ๋‹ค๋Š” ๊ฑด ์ง€๋„(a)์— ๋ง์น˜์งˆ(button)ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™๋‹ค."

๊ทธ๋ฆฌ๊ณ  rel='noopener noreferrer' ์ด๊ฑฐ... ์ด๋ ‡๊ฒŒ ์ค‘์š”ํ•œ ๋ณด์•ˆ ์†์„ฑ์ด์—ˆ๋Š”์ง€ ๋ชฐ๋ž๋‹ค. ์•ž์œผ๋กœ๋Š” ์™ธ๋ถ€ ๋งํฌ ์“ธ ๋•Œ reflexively(๋ฐ˜์‚ฌ์ ์œผ๋กœ) ๋ถ™์—ฌ์•ผ๊ฒ ๋‹ค. ์˜ค๋Š˜ ์ €๋…์€ ๋ฐฅ ๋จน์œผ๋ฉด์„œ Next.js Link ์ปดํฌ๋„ŒํŠธ prefetch ๋™์ž‘ ๋” ํŒŒ๋ด์•ผ์ง€.


๐Ÿ”— ๋” ์•Œ์•„๋ณด๊ธฐ