231008(μΌ) μ±μ₯
π€ μ±μ₯μΌμ§ 7.0
μ±
ν볡ν μ΄κΈ°μ£Όμμ(μ¨μΈ λ€μ΄μ΄)
μ λ΄μ©μ μκ·Ήλ°μ μμνλ μλ°ν μ±μ₯κΈ°λ‘
μ΄μμλ κ½κ³Ό μ£½μ κ½μ μ΄λ»κ² ꡬλ³νλκ°?
μ±μ₯νκ³ μλ κ²μ΄ μ΄μ μλ κ²μ΄λ€.
μλͺ μ μ μΌν μ¦κ±°λ μ±μ₯μ΄λ€!
β (7.0)<μμ κ°νΈ>
νμΈλ§ νμ΅λ²
μ μκ² λλ§νΌ, μ±μ₯μΌμ§λ μ λ§ κ·Έ λ μ ν€μλ μ€μ¬μΌλ‘ κ°λ¨νκ² μ 리νλλ‘ νλ€.
tailwind theme with light, dark mode
λ³΄ν΅ μ°λ¦¬κ° μ£Όμ΄μ§ λμμΈμ ν λλ‘ κ°λ°νκ² λ λλ μ ν΄μ§ μμ, ν¬κΈ°, ν°νΈ λ±μ μ ν΄λκ³ μμνλ€.(λμ±μ΄ λμμ΄λλΆκ»μ μ μ 리λ λμμΈ μμ€ν
ννλ‘ μμ±ν΄μ£Όμλ©΄ μ΅κ³ !)
μ¦, tailwindμ λͺ¨λ κ°λ€μ μ¬μ©ν νμκ° μλ€λ κ²μ΄λ€. μ΄λ΄ λ theme
λ₯Ό μ΄μ©ν΄μ νμν κ°λ€λ§ μ μν΄λκ³ μ¬μ©νλ©΄ λλ€.
import type { Config } from 'tailwindcss';
const config: Config = {
theme: {
colors: {
primary: {
light: '#0FC5FF',
dark: '#0FC5FF',
},
secondary: {
light: '#8B54FF',
dark: '#8B54FF',
},
white: {
light: '#FFFFFF',
dark: '#FFFFFF',
},
black: {
light: '#000000',
dark: '#000000',
},
gray_00: {
light: '#FFFFFF',
dark: '#292F3F',
},
gray_01: {
light: '#F5F5F5',
dark: '#3B4359',
},
gray_02: {
light: '#EEEEEE',
dark: '#32394B',
},
gray_03: {
light: '#666666',
dark: '#9096A9',
},
gray_04: {
light: '#666666',
dark: '#EEEEEE',
},
gray_05: {
light: '#292F3F',
dark: '#FFFFFF',
},
shadow: {
light:
'0px 0px 16px 0px rgba(218, 226, 231, 0.3), 0px 24px 24px 0px rgba(181, 190, 197, 0.3)',
dark: '0px 0px 16px 0px rgba(0, 0, 0, 0.20), 0px 24px 24px 0px rgba(0, 0, 0, 0.20)',
},
card: {
light: '#FFFFFF',
dark: '#3B4359',
},
},
fontSize: {
x_small: '12px',
small: '14px',
medium: '16px',
large: '18px',
x_large: '24px',
xx_large: '30px',
},
fontWeight: {
normal: '400',
semi_bold: '500',
bold: '700',
},
},
content: [
'./src/pages/**/*.{js,ts,jsx,tsx,mdx}',
'./src/components/**/*.{js,ts,jsx,tsx,mdx}',
'./src/app/**/*.{js,ts,jsx,tsx,mdx}',
],
darkMode: 'class',
plugins: [],
};
export default config;
λ¨, μ£Όμν μ μ μμ κ°μ΄ themeμ μ€μ νκ² λλ©΄ κΈ°μ‘΄μ tailwind κ°λ€μ λͺ¨λ 무μλλ€λ κ²μ΄λ€. λ°λΌμ κΈ°μ‘΄μ tailwind κ°λ€μ μ¬μ©νκ³ μΆλ€λ©΄ extend
λ₯Ό μ΄μ©ν΄μ μΆκ°ν΄μ£Όμ΄μΌ νλ€.
import type { Config } from 'tailwindcss';
const config: Config = {
theme: {
extend: {
colors: {
// ... μ€λ΅
},
},
},
};
μ μ μλ theme κ°λ€μ΄ μλ€λ©΄ extendλ₯Ό μ¬μ©νλ 건 μ€νλ € λΆνΈν΄μ§λ κ² κ°λ€. μμΉ«νλ©΄ μ°λ¦¬ μλΉμ€μμ μ¬μ©νμ§ μλ κ°λ€μ μΈ μλ μκ³ μ€νλ € λμμΈμ΄ μΆκ°λ λ, configλ‘ λμκ°μ μΆκ°ν΄μ£Όλ κ² λ λμ κ² κ°λ€!
Next Image
Next.jsμμ μ΄λ―Έμ§λ₯Ό μ¬μ©ν λλ next/image
λ₯Ό μ¬μ©νλ©΄ λλ€. μλμ κ°μ΄ μ¬μ©νλ©΄ λλ€.
import Image from 'next/image';
export default function Logo() {
return (
<section className="flex justify-between gap-[6px]">
<Image
src="/images/logo/character.png"
alt="λ² μ€νΈλΌλΉμ€ λ‘κ³ μΊλ¦ν°"
width={36}
height={36}
/>
<Image
src="/images/logo/title.png"
alt="λ² μ€νΈλΌλΉμ€ λ‘κ³ νμ΄ν"
width={120}
height={20}
className="h-[20px]"
/>
</section>
);
}
μ΄ λ, next/imageλ κΈ°λ³Έμ μΌλ‘ μ¬λ¬κ°μ§ μ΄λ―Έμ§ μ΅μ νλ₯Ό μ§μνλλ°, svgμ λν΄μλ μ§μνμ§ μλλ€. κ·Έ μ΄μ λ μλμ κ°λ€.
The default loader does not optimize SVG images for a few reasons. First, SVG is a vector format meaning it can be resized losslessly. Second, SVG has many of the same features as HTML/CSS, which can lead to vulnerabilities without a proper Content Security Policy.
κΈ°λ³Έ λ‘λλ λͺ κ°μ§ μ΄μ λ‘ SVG μ΄λ―Έμ§λ₯Ό μ΅μ ννμ§ μμ΅λλ€. 첫째, SVGλ λ²‘ν° νμμ΄λ―λ‘ μμ€ μμ΄ ν¬κΈ°λ₯Ό μ‘°μ ν μ μμ΅λλ€. λμ§Έ, SVGμλ HTML/CSSμ λμΌν κΈ°λ₯μ΄ λ§κΈ° λλ¬Έμ μ μ ν μ½ν
μΈ λ³΄μ μ μ±
μ΄ μμΌλ©΄ μ·¨μ½μ μ΄ λ°μν μ μμ΅λλ€.
π νκ³
νμ€ν μ΄λ°μλ λλ μ§λ§ νλ€λ³΄λκΉ μ μ°¨ μλκ° λΆλ κ² κ°λ€. next.jsμ 곡μλ¬Έμκ° μ λ§ μ λ¦¬κ° μλμ΄μλ λλΆμ΄λ€. react 곡μλ¬Έμ보λ€λ ν¨μ¬ λ μ μ λ¦¬κ° λμ΄μλ κ² κ°λ€ ννβ¦ μ½μ§ μμ§λ§ μ΄μ λ§μ΄κ·Έλ μ΄μ νκΈ°λ‘ ν κ±° κ³μ κΎΈμ€ν ν΄λ΄μΌκ² λ€..! κ·Έλ¬λ©΄μ 리μ‘νΈ μ체μ λν κΉμ΄ μλ μ΄ν΄λλ λμ΄λλ‘ νμ!