Download as pdf or txt
Download as pdf or txt
You are on page 1of 36

Getting deeply into

How does it work? And, how to make it?


ページ構造を知ろう
vcborn-new

emails

public

src

components

locales

pages
vcborn-new

emails HTMLメールのテンプレート
public

src

components

locales

pages
vcborn-new

emails 画像ファイルなどの静的ファイル
public

src

components

locales

pages
vcborn-new

emails コンポーネント
public

src

components

locales

pages
vcborn-new

emails 言語
public

src

components

locales

pages
vcborn-new

emails 各ページ
public https://vcborn.com/services/vclinux

src
src/pages/services/vclinux.tsx
components
https://vcborn.com/about
locales
src/pages/about.tsx
pages
詳しくはREADME.md
(簡単な)JSXの構成
import Layout, { siteTitle } from "../components/layout";
import Head from "next/head";
import { useLocale } from "../hooks/useLocale";
import nl2br from "react-nl2br"; import 名前 from 場所
import Adsense from "../components/Adsense";

export default function About() { 使いたい関数や変数を取ってくる


const { t } = useLocale(); 場所はライブラリ名だったりパスだったりする
return (
<Layout home={undefined}>
<Head>
<title>
{t.ABOUTUS} | {siteTitle}
</title>
<meta
property="og:image"
content={`${process.env.NEXT_PUBLIC_SITE_URL}/images/ogp.jpg`}
/>
</Head>
<article className="pt-10 h-[60vh] container mx-auto px-5 max-w-5xl
motion-safe:animate-fadeIn">
<h1 className="text-4xl font-bold mb-3">{t.ABOUTUS}</h1>
<p className="text-lg mb-5">
{t.ABOUT}
<br />
{nl2br(`${t.ABOUT_LONG}`)}
<br />
</p>
<Adsense />
</article>
</Layout>
);
}
import Layout, { siteTitle } from "../components/layout";
import Head from "next/head";
import { useLocale } from "../hooks/useLocale";
import nl2br from "react-nl2br"; export default function Name()
import Adsense from "../components/Adsense";

export default function About() {


const { t } = useLocale();
return ( export:
<Layout home={undefined}> 関数や変数を出力
<Head>
<title>
{t.ABOUTUS} | {siteTitle}
</title>
default:
<meta モジュールとして出力(単一)
property="og:image"
content={`${process.env.NEXT_PUBLIC_SITE_URL}/images/ogp.jpg`}
/> function Name()
</Head>
<article className="pt-10 h-[60vh] container mx-auto px-5 max-w-5xl 関数の宣言
motion-safe:animate-fadeIn">
<h1 className="text-4xl font-bold mb-3">{t.ABOUTUS}</h1>
<p className="text-lg mb-5">
{t.ABOUT}
ページを出力するときはこれにすればいいと思う
<br />
{nl2br(`${t.ABOUT_LONG}`)}
<br />
</p>
<Adsense />
</article>
</Layout>
);
}
import Layout, { siteTitle } from "../components/layout";
import Head from "next/head";
import { useLocale } from "../hooks/useLocale"; {変数}
import nl2br from "react-nl2br";
import Adsense from "../components/Adsense";
HTML内部で宣言した変数を表示
export default function About() {
const { t } = useLocale();
return (
<Layout home={undefined}> {t.キー名}
<Head>
<title>
{t.ABOUTUS} | {siteTitle} 各言語のテキストを呼び出し
</title>
<meta
property="og:image"
content={`${process.env.NEXT_PUBLIC_SITE_URL}/images/ogp.jpg`}
/>
</Head>
<article className="pt-10 h-[60vh] container mx-auto px-5 max-w-5xl
motion-safe:animate-fadeIn">
<h1 className="text-4xl font-bold mb-3">{t.ABOUTUS}</h1>
<p className="text-lg mb-5">
{t.ABOUT}
<br />
{nl2br(`${t.ABOUT_LONG}`)}
<br />
</p>
<Adsense />
</article>
</Layout>
);
}
import Layout, { siteTitle } from "../components/layout";
import Head from "next/head";
import { useLocale } from "../hooks/useLocale";
import nl2br from "react-nl2br"; return ()
import Adsense from "../components/Adsense";

export default function About() { 戻り値を返す


const { t } = useLocale(); export defaultと一緒に覚えておけばよい
return (
<Layout home={undefined}>
<Head>
<title>
{t.ABOUTUS} | {siteTitle}
</title>
<meta
property="og:image"
content={`${process.env.NEXT_PUBLIC_SITE_URL}/images/ogp.jpg`}
/>
</Head>
<article className="pt-10 h-[60vh] container mx-auto px-5 max-w-5xl
motion-safe:animate-fadeIn">
<h1 className="text-4xl font-bold mb-3">{t.ABOUTUS}</h1>
<p className="text-lg mb-5">
{t.ABOUT}
<br />
{nl2br(`${t.ABOUT_LONG}`)}
<br />
</p>
<Adsense />
</article>
</Layout>
);
}
import Layout, { siteTitle } from "../components/layout";
import Head from "next/head";
import { useLocale } from "../hooks/useLocale";
import nl2br from "react-nl2br"; <コンポーネント名></コンポーネント名>
import Adsense from "../components/Adsense";

export default function About() { コンポーネントを表示(挿入)


const { t } = useLocale();
return (
<Layout home={undefined}> ・コンポーネント指向
<Head> ・Atomic Designに近いかも
<title>
{t.ABOUTUS} | {siteTitle}
</title>
<meta
property="og:image"
content={`${process.env.NEXT_PUBLIC_SITE_URL}/images/ogp.jpg`}
/>
</Head>
<article className="pt-10 h-[60vh] container mx-auto px-5 max-w-5xl
motion-safe:animate-fadeIn">
<h1 className="text-4xl font-bold mb-3">{t.ABOUTUS}</h1>
<p className="text-lg mb-5">
{t.ABOUT}
<br />
{nl2br(`${t.ABOUT_LONG}`)}
<br />
</p>
<Adsense />
</article>
</Layout>
);
}
import Layout, { siteTitle } from "../components/layout";
import Head from "next/head";
import { useLocale } from "../hooks/useLocale";
import nl2br from "react-nl2br"; <Head></Head>
import Adsense from "../components/Adsense";

export default function About() { <head>にコードを追加したいときに使うもの


const { t } = useLocale(); タイトルやOGPをここに入れる
return (
<Layout home={undefined}>
<Head>
<title>
{t.ABOUTUS} | {siteTitle}
</title>
<meta
property="og:image"
content={`${process.env.NEXT_PUBLIC_SITE_URL}/images/ogp.jpg`}
/>
</Head>
<article className="pt-10 h-[60vh] container mx-auto px-5 max-w-5xl
motion-safe:animate-fadeIn">
<h1 className="text-4xl font-bold mb-3">{t.ABOUTUS}</h1>
<p className="text-lg mb-5">
{t.ABOUT}
<br />
{nl2br(`${t.ABOUT_LONG}`)}
<br />
</p>
<Adsense />
</article>
</Layout>
);
}
(ざっくり)JSXの規則
import Layout, { siteTitle } from "../components/layout";
import Head from "next/head";
import { useLocale } from "../hooks/useLocale";
import nl2br from "react-nl2br"; ・ページは必ず一つの要素
import Adsense from "../components/Adsense";

export default function About() { return内部では必ず一つの要素で包む


const { t } = useLocale();
return ( 二つ以上あるとエラーを吐くよ
<div>
<Head>
<title>
{t.ABOUTUS} | {siteTitle}
</title>
<meta
property="og:image"
content={`${process.env.NEXT_PUBLIC_SITE_URL}/images/ogp.jpg`}
/>
</Head>
<article className="pt-10 h-[60vh] container mx-auto px-5 max-w-5xl
motion-safe:animate-fadeIn">
<h1 className="text-4xl font-bold mb-3">{t.ABOUTUS}</h1>
<p className="text-lg mb-5">
{t.ABOUT}
<br />
{nl2br(`${t.ABOUT_LONG}`)}
<br />
</p>
<Adsense />
</article>
</div>
<div></div>
);
}
import Layout, { siteTitle } from "../components/layout";
import Head from "next/head";
import { useLocale } from "../hooks/useLocale";
import nl2br from "react-nl2br"; ・classはclassNameと書く
import Adsense from "../components/Adsense";

export default function About() { JSXではクラスはclassNameで定義します


const { t } = useLocale(); classではありません(間違えやすい)
return (
<div>
<Head>
<title>
{t.ABOUTUS} | {siteTitle}
</title>
<meta
property="og:image"
content={`${process.env.NEXT_PUBLIC_SITE_URL}/images/ogp.jpg`}
/>
</Head>
<article className="pt-10 h-[60vh] container mx-auto px-5 max-w-5xl
motion-safe:animate-fadeIn">
<h1 className="text-4xl font-bold mb-3">{t.ABOUTUS}</h1>
<p class="text-lg mb-5">
{t.ABOUT}
<br />
{nl2br(`${t.ABOUT_LONG}`)}
<br />
</p>
<Adsense />
</article>
</div>
);
}
import Layout, { siteTitle } from "../components/layout";
import Head from "next/head";
import { useLocale } from "../hooks/useLocale";
import nl2br from "react-nl2br"; ・必ず閉じタグを入れる
import Adsense from "../components/Adsense";

export default function About() { JSXは閉じタグを省略できません


const { t } = useLocale();
return (
<div>
<Head>
<title>
{t.ABOUTUS} | {siteTitle}
</title>
<meta
property="og:image"
content={`${process.env.NEXT_PUBLIC_SITE_URL}/images/ogp.jpg`}
>
</Head>
<article className="pt-10 h-[60vh] container mx-auto px-5 max-w-5xl
motion-safe:animate-fadeIn">
<h1 className="text-4xl font-bold mb-3">{t.ABOUTUS}</h1>
<p class="text-lg mb-5">
{t.ABOUT}
<br>
{nl2br(`${t.ABOUT_LONG}`)}
<br>
</p>
<Adsense />
</article>
</div>
);
}
JSXでHello Worldする
src/components/Hello.jsx

const Hello = () => (


<h1>Hello World</h1>
)

export default Hello;


src/pages/_app.jsx

import Hello from "../components/Hello“;

export default function App() {


return <Hello />;
}
npm run buildで表示
Tailwind教なのでCSSの話はしません
便利な使い方
例えばこんな変数があったとして…
const creators = [
{
"username": "example",
"desc": "example"
},
{
"username": "example",
"desc": "example"
},
.
.
.
];
こうすれば…
export default function Example() {
return (
{creators.map((item, index) => {
return (
<h3 className="text-2xl font-bold">{item.username}</h3>
<p>{item.description}</p>
)
}
)
}
こうなる
応募フォームの仕組み
ボタンが押された 文字を置き換え

No Yes
バリデーション エラー表示 レート制限 エラー表示

Yes
No

No Error
reCAPTCHA エラー表示 sendgridで送信 エラー表示

Yes
Error
discordに送信 エラー表示
ールテンプレートを読み込み

Text is not SVG - cannot display


src/pages/api内のページはAPIとして呼び出せる
vcborn-new

POST https://vcborn.com/api/sendgrid
emails
param: {フォームに入力された情報}

public -> HTTP 200

src
GET https://vcborn.com/api/data
components -> {メンバー情報}

locales
データの必要ないトランザクションならGETで飛ばせばできる
データの必要あるものはPOSTで送ればデータを取得できる
pages

api
バックエンドを別に作る必要がない
まとめ
動作だけ理解してればOK
何となく動作を予測することが大切

You might also like