TL;DR
この記事では、Next.js と TypeScript を活用し、SNS ボタンを作成する方法を紹介します。
| 開発環境 | バージョン |
|---|---|
| Next.js | 13.4.3 |
| TypeScript | 5.0.4 |
| Emotion | 11.11.0 |
| React | 18.2.0 |
全体のコード
次のコードは、Next.js と TypeScript、そして Emotion を利用して 2 つの SNS ボタン (Twitter、Facebook) を作成するものです。各ボタンは、指定された URL と タイトルを利用して対象の SNS でのシェア機能を持つようになっています。
// components/SnsBtn.tsx
import React from 'react'
import styled from '@emotion/styled'
const SnsButtons = styled.div`
margin-bottom: 20px;
display: grid;
gap: 8px;
`
const Button = styled.a`
display: grid;
place-content: center;
width: 30px;
height: 30px;
padding: 8px 12px;
font-size: 14px;
text-decoration: none;
`
const TwitterButton = styled(Button)`
background-color: #55acee;
color: #fff;
`
const FacebookButton = styled(Button)`
background-color: #3b5998;
color: #fff;
`
type Props = {
url: string
title: string
}
const SnsBtn = ({ url, title }: Props) => {
const encodedUrl = encodeURIComponent(url)
const encodedTitle = encodeURIComponent(title)
return (
<SnsButtons>
<TwitterButton href={`https://twitter.com/share?url=${encodedUrl}&text=${encodedTitle}`} target="_blank" rel="noopener noreferrer">
<img src="/icon/white/twitter-brands.svg" alt="Twitter" width="20" height="20" />
</TwitterButton>
<FacebookButton href={`https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`} target="_blank" rel="noopener noreferrer">
<img src="/icon/white/facebook-brands.svg" alt="Facebook" width="20" height="20" />
</FacebookButton>
</SnsButtons>
)
}
export default SnsBtn
コードの解説
それではコードを詳しく見ていきましょう。
import React from 'react'
import styled from '@emotion/styled'
まず、React と Emotion の styled 関数をインポートしています。Emotion の styled 関数は、CSS in JS を利用して React コンポーネントのスタイリングを行うことができます。
const SnsButtons = styled.div`
margin-bottom: 20px;
display: grid;
gap: 8px;
`
ここでは SNS ボタンを格納するためのコンテナとなる SnsButtons コンポーネントを定義しています。grid ディスプレイが設定され、ボタン間のギャップも定められています。
const Button = styled.a`
display: grid;
place-content: center;
border-radius: 50%;
width: 50px;
height: 50px;
padding: 8px 12px;
font-size: 14px;
text-decoration: none;
`
次に、一般的なボタンスタイルを持つ Button コンポーネントを定義しています。このスタイルは、すべての SNS ボタンで共通して適用されます。
const TwitterButton = styled(Button)`
background-color: #55acee;
color: #fff;
`
const FacebookButton = styled(Button)`
background-color: #3b5998;
color: #fff;
`
上記では、各 SNS に特有の色を背景色として設定し、テキストの色を白に設定することで、Twitter と Facebook のボタンを個別にスタイリングしています。
type Props = {
url: string
title: string
}
ここで、コンポーネントの Props を定義しています。これらの Props は、各 SNS のシェア機能で使用されます。
const SnsBtn = ({ url, title }: Props) => {
const encodedUrl = encodeURIComponent(url)
const encodedTitle = encodeURIComponent(title)
//...
}
コンポーネント SnsBtn は、受け取った url と title をエンコードし、それぞれを encodedUrl と encodedTitle として保存します。
return (
<SnsButtons>
<TwitterButton href={`https://twitter.com/share?url=${encodedUrl}&text=${encodedTitle}`} target="_blank" rel="noopener noreferrer">
<img
src="/icon/twitter.svg"
alt="Twitter"
width="20
"
height="20"
/>
</TwitterButton>
<FacebookButton href={`https://www.facebook.com/sharer/sharer.php?u=${encodedUrl}`} target="_blank" rel="noopener noreferrer">
<img src="/icon/facebook.svg" alt="Facebook" width="20" height="20" />
</FacebookButton>
</SnsButtons>
)
return にて、エンコードされた url と title を用いて Twitter と Facebook のボタンがレンダリングされます。これらのボタンはそれぞれの SNS のシェアリンクを持っており、ボタンをクリックすると新しいタブで該当のシェアリンクが開きます。
最後に、コンポーネントをエクスポートします。他のファイルからこのコンポーネントをインポートして使用できるようにするためのステップです。
コンポーネントを呼び出す
この SnsBtn コンポーネントを呼び出すには、以下のような形で行います。
import SnsBtn from './components/SnsBtn'
// あるコンポーネント内での利用例
function ExampleComponent() {
const url = 'https://example.com' // シェアしたいURL
const title = 'Example title' // シェアしたいタイトル
return (
<div>
<h1>Some content here...</h1>
<SnsBtn url={url} title={title} />
</div>
)
}
export default ExampleComponent
上記の例ではまず、SnsBtn コンポーネントを import 文を用いてインポートしています。次に、ExampleComponent 内で SnsBtn コンポーネントを使用しています。
SnsBtn コンポーネントは、url と title の 2 つの props を必要とします。これらの値は、各 SNS のシェアリンクを生成するために使用されます。
url prop はシェアしたいウェブページの URL、title prop はそのページのタイトルを表しています。上記の例では 'https://example.com' と 'Example title' をそれぞれの値として設定していますが、実際の使用では、対象となるウェブページの URL とタイトルを指定します。
このようにして SnsBtn コンポーネントを呼び出すと、指定した URL とタイトルで各 SNS にシェアするためのボタンが表示されます。ユーザーがこれらのボタンをクリックすると、新しいタブが開き、該当の SNS で指定された URL とタイトルをシェアすることができます。
環境変数を使う
記事ごとに動的なタイトルを呼び出すには、次のように環境変数を使用します。
Next.js では、[id].tsx のような動的ルーティングが利用できます。その際、ブログ記事などの特定のコンテンツを指すために、その ID を URL の一部として用いることが多いです。
以下に、Next.js の動的ページで、環境変数を使って SNS シェアボタンを実装する例を記載します。
まず、.env.local ファイル(あるいは対応する環境設定ファイル)にウェブサイトのベース URL を設定します。NEXT_PUBLIC_SITE_URL という名前で設定します。
NEXT_PUBLIC_SITE_URL=https://example.comそして、 [id].tsx ファイルを次のように実装します。
// pages/[id].tsx
import { GetStaticProps, GetStaticPaths } from 'next'
import SnsBtn from '../components/SnsBtn'
type PostData = {
id: string
title: string
// 必要に応じて他のフィールドを追加
}
type Props = {
postData: PostData
}
const PostPage = ({ postData }: Props) => {
const url = `${process.env.NEXT_PUBLIC_SITE_URL}/${postData.id}`
return (
<div>
<h1>{postData.title}</h1>
{/* ブログ記事の内容を表示 */}
<SnsBtn url={url} title={postData.title} />
</div>
)
}
export default PostPage
export const getStaticPaths: GetStaticPaths = async () => {
// ブログ記事のIDを全て取得し、paths を生成
const paths = /* IDの配列を取得する処理 */
return { paths, fallback: false }
}
export const getStaticProps: GetStaticProps = async ({ params }) => {
// ブログ記事のデータを取得
const postData: PostData = /* IDをもとにデータを取得する処理 */
return { props: { postData } }
}
ここでは、動的なページの生成を行う getStaticPaths と getStaticProps を利用しています。それぞれが必要なデータの取得やパスの生成を行います。
getStaticPaths は静的生成が必要な全てのパス(この場合、全ブログ記事の ID)を返します。そして getStaticProps は、各パスに対するプロパティ(この場合、各ブログ記事のデータ)を返します。
このようにすることで、各ブログ記事ページに適切な URL とタイトルが設定された SNS シェアボタンが配置されます。