diff --git a/package.json b/package.json index 16f4468..3d62ca9 100644 --- a/package.json +++ b/package.json @@ -30,6 +30,7 @@ "axios": "^1.13.4", "react": "^19.2.0", "react-dom": "^19.2.0", + "react-helmet-async": "^3.0.0", "react-router": "^7.13.0" }, "devDependencies": { diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index abea281..773d327 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -38,6 +38,9 @@ importers: react-dom: specifier: ^19.2.0 version: 19.2.4(react@19.2.4) + react-helmet-async: + specifier: ^3.0.0 + version: 3.0.0(react@19.2.4) react-router: specifier: ^7.13.0 version: 7.13.0(react-dom@19.2.4(react@19.2.4))(react@19.2.4) @@ -1580,6 +1583,9 @@ packages: inherits@2.0.4: resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} + invariant@2.2.4: + resolution: {integrity: sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==} + is-arrayish@0.2.1: resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} @@ -1974,6 +1980,14 @@ packages: peerDependencies: react: ^19.2.4 + react-fast-compare@3.2.2: + resolution: {integrity: sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ==} + + react-helmet-async@3.0.0: + resolution: {integrity: sha512-nA3IEZfXiclgrz4KLxAhqJqIfFDuvzQwlKwpdmzZIuC1KNSghDEIXmyU0TKtbM+NafnkICcwx8CECFrZ/sL/1w==} + peerDependencies: + react: ^16.6.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 + react-is@16.13.1: resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} @@ -2095,6 +2109,9 @@ packages: set-cookie-parser@2.7.2: resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==} + shallowequal@1.1.0: + resolution: {integrity: sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ==} + shebang-command@2.0.0: resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} engines: {node: '>=8'} @@ -4335,6 +4352,10 @@ snapshots: inherits@2.0.4: {} + invariant@2.2.4: + dependencies: + loose-envify: 1.4.0 + is-arrayish@0.2.1: {} is-arrayish@0.3.4: {} @@ -4683,6 +4704,15 @@ snapshots: react: 19.2.4 scheduler: 0.27.0 + react-fast-compare@3.2.2: {} + + react-helmet-async@3.0.0(react@19.2.4): + dependencies: + invariant: 2.2.4 + react: 19.2.4 + react-fast-compare: 3.2.2 + shallowequal: 1.1.0 + react-is@16.13.1: {} react-refresh@0.18.0: {} @@ -4768,6 +4798,8 @@ snapshots: set-cookie-parser@2.7.2: {} + shallowequal@1.1.0: {} + shebang-command@2.0.0: dependencies: shebang-regex: 3.0.0 diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..45d8777 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,7 @@ +User-agent: * +Allow: / +Disallow: /mypage +Disallow: /upload +Disallow: /project/ + +Sitemap: https://www.seedlab.cloud/sitemap.xml diff --git a/public/sitemap.xml b/public/sitemap.xml new file mode 100644 index 0000000..3c3b381 --- /dev/null +++ b/public/sitemap.xml @@ -0,0 +1,6 @@ + + + + https://www.seedlab.cloud/ + + diff --git a/src/app/providers/ApplicationProviders.tsx b/src/app/providers/ApplicationProviders.tsx index 94de2fe..19b6d56 100644 --- a/src/app/providers/ApplicationProviders.tsx +++ b/src/app/providers/ApplicationProviders.tsx @@ -1,3 +1,5 @@ +import { HelmetProvider } from "react-helmet-async"; + import { Toaster } from "@/shared"; import { AuthProvider, QueryProvider, ThemeProvider } from "./components"; @@ -8,13 +10,15 @@ type Props = { export const ApplicationProviders = ({ children }: Props) => { return ( - - - - {children} - - - - + + + + + {children} + + + + + ); }; diff --git a/src/pages/login/LoginPage.tsx b/src/pages/login/LoginPage.tsx index 8588e86..df67d68 100644 --- a/src/pages/login/LoginPage.tsx +++ b/src/pages/login/LoginPage.tsx @@ -5,10 +5,12 @@ import { LoginHelpSection, LoginTitleText, } from "@/features"; +import { LOGIN_PAGE_SEO, Seo } from "@/shared"; export default function LoginPage() { return ( + - - + + + - - - + + + + 생산성 +50% 로켓 탑승하기 + + + + 오래 걸리는 과제, +
+ + 3단계로 압축하세요. + +
+ + - 생산성 +50% 로켓 탑승하기 + PDF 업로드 한 번으로 + + + {" "} + + 과제 로드맵부터 최적화 프롬프트까지. -
+
- + + +
+
+ + + + + - 오래 걸리는 과제, -
- 3단계로 압축하세요. + 프롬프트 창 앞에서 + + + {" "} + 망설이지 마세요. + +
+ 정답은 이미 + + + {" "} + SEED{" "} + + 에 있습니다. - - - - PDF 업로드 한 번으로 - - - {" "} + + 수만 개의 성공적인 프롬프트 데이터와 + 당신의 + 과제물의 분석을 통해 +
각 로드맵에 최적화된 프롬프트를 제공합니다.
- 과제 로드맵부터 최적화 프롬프트까지. -
-
+
- - + + + + + + + + + + + + Step 3 최적화 프롬프트 + + + 논문형 + + + + + + + + + + # Role: Academic Writer +
+ # Task: Draft an assignment based on roadmap +
+
+ [Context] +
+ Based on the previously summarized materials +
+ regarding 'Inflation Impact', please draft a
+ comprehensive introduction. Include the +
+ following key arguments: ... +
+
+ [Constraints] +
+ - Use formal academic tone. +
- Cite sources in APA format. +
+
+
+
+
+ + + 바로 복사해서 +
+ 결과를 만들어보세요. +
+ + + 로드맵 각 단계에 꼭 맞는 + + 최적의 프롬프트가 생성됩니다. +
+ 고민 없이 '복사' 버튼 하나면 +
+ 전문적인 결과물로 이어질 수 있습니다. +
+ + + {[ + "단계별 맞춤형 프롬프트 제공", + "원클릭 복사 및 재생성", + "검증된 학술적 구조 적용", + ].map((feature) => { + return ( + + + + + + {feature} + + + ); + })} + +
+
- -
- - - - + - - + - 프롬프트 창 앞에서 - + 이제 과제는{" "} - {" "} - 망설이지 마세요. + 어떻게 + 가 아니라
- 정답은 이미 - - {" "} - SEED{" "} + 무엇을{" "} - 에 있습니다. - - + - 수만 개의 성공적인 프롬프트 데이터와 - 당신의 - 과제물의 분석을 통해 -
각 로드맵에 최적화된 프롬프트를 제공합니다. -
+ 막막하던 과제의 시작부터 배경과 마무리까지, +
+ SEED가 설계한 로드맵과 프롬프트가 함께 합니다. +
- - - - - - - - - - - - - - Step 3 최적화 프롬프트 - - - 논문형 - - - - - - - - - - # Role: Academic Writer -
- # Task: Draft an assignment based on roadmap -
-
- [Context] -
- Based on the previously summarized materials -
- regarding 'Inflation Impact', please draft a
- comprehensive introduction. Include the -
- following key arguments: ... -
-
- [Constraints] -
- - Use formal academic tone. -
- Cite sources in APA format. -
-
-
-
-
- - - 바로 복사해서 -
- 결과를 만들어보세요. -
- - - 로드맵 각 단계에 꼭 맞는 - - 최적의 프롬프트가 생성됩니다. -
- 고민 없이 '복사' 버튼 하나면 -
- 전문적인 결과물로 이어질 수 있습니다. -
- - - {[ - "단계별 맞춤형 프롬프트 제공", - "원클릭 복사 및 재생성", - "검증된 학술적 구조 적용", - ].map((feature) => { - return ( - - - - - - {feature} - - - ); - })} - -
-
-
-
- - - - 이제 과제는{" "} - - 어떻게 - - 가 아니라 -
- - 무엇을{" "} - - 할 지만 고민하세요. -
- - 막막하던 과제의 시작부터 배경과 마무리까지, -
- SEED가 설계한 로드맵과 프롬프트가 함께 합니다. -
-
-
- + + + ); } diff --git a/src/shared/components/features/Seo.tsx b/src/shared/components/features/Seo.tsx new file mode 100644 index 0000000..d243de5 --- /dev/null +++ b/src/shared/components/features/Seo.tsx @@ -0,0 +1,25 @@ +import { Helmet } from "react-helmet-async"; + +import { DEFAULT_SEO, type SeoConfig } from "../../constants"; + +const BASE_URL = "https://www.seedlab.cloud"; + +type Props = { + config?: SeoConfig; +}; + +export const Seo = ({ config = DEFAULT_SEO }: Props) => ( + + {config.title} + + {config.noindex && } + {config.path && } + + + {config.path && ( + + )} + + + +); diff --git a/src/shared/components/features/index.ts b/src/shared/components/features/index.ts index 39ed4ce..3caa8fd 100644 --- a/src/shared/components/features/index.ts +++ b/src/shared/components/features/index.ts @@ -1,2 +1,3 @@ export * from "./CreateIcon"; +export * from "./Seo"; export * from "./Toaster"; diff --git a/src/shared/constants/index.ts b/src/shared/constants/index.ts index ae72c70..6c99a4d 100644 --- a/src/shared/constants/index.ts +++ b/src/shared/constants/index.ts @@ -1,3 +1,4 @@ export * from "./error-message"; export * from "./route-path"; +export * from "./seo"; export * from "./server-path"; diff --git a/src/shared/constants/seo.ts b/src/shared/constants/seo.ts new file mode 100644 index 0000000..a4b7c28 --- /dev/null +++ b/src/shared/constants/seo.ts @@ -0,0 +1,19 @@ +export type SeoConfig = { + title: string; + description: string; + path?: string; + noindex?: boolean; +}; + +export const DEFAULT_SEO: SeoConfig = { + title: "과제 고민 끝, 대학생 맞춤형 AI 프롬프트 가이드 - SEED", + description: + "수만 개의 성공적인 프롬프트 데이터로 당신의 과제에 딱 맞는 로드맵을 제시합니다. 원클릭 복사로 논문, 레포트 등 완벽한 결과물을 만들어보세요.", + path: "/", +}; + +export const LOGIN_PAGE_SEO: SeoConfig = { + title: "로그인 - SEED", + description: "SEED에 로그인하세요.", + noindex: true, +}; diff --git a/src/widgets/layout/components/footer/Footer.tsx b/src/widgets/layout/components/footer/Footer.tsx index f0d81a2..3391bca 100644 --- a/src/widgets/layout/components/footer/Footer.tsx +++ b/src/widgets/layout/components/footer/Footer.tsx @@ -18,13 +18,7 @@ export const Footer = () => { position="relative" > - Seed Logo + SEED { position="relative" > - Seed Logo + SEED {!isAuthenticated && (