2023-02-11

analytics

Posted by

applemango

ユーザーからフィードバックを得る方法は色々ありますが今回はユーザーがワンクリックで評価できる絵文字を使った方法を書きます

またそれと同時に今回はGoogle AnalyticsのEventをBackend代わりとして使うため簡単な結果を見る方法もついでに書く

おまけとしてNext.jsでの方法も最後にあります

それでは早速作って行きましょう、今回は以下のような見た目になります

適当にデザインする

まず適当なデザインを決め、CSSを書きます

因みに今回は絵文字にtwitter/twemojiを使っています

そのうち使っている絵文字は以下の四つです

<div class="form">
    <p>このドキュメントどう?</p>
    <div class="emojis">
        <div class="emoji" score="0">
            <img src="/emoji/1f62d.svg" alt="emoji" width="32" height="32" />
        </div>
        <div class="emoji" score="1">
            <img src="/emoji/1f615.svg" alt="emoji" width="32" height="32" />
        </div>
        <div class="emoji" score="2">
            <img src="/emoji/1f600.svg" alt="emoji" width="32" height="32" />
        </div>
        <div class="emoji" score="3">
            <img src="/emoji/1f60d.svg" alt="emoji" width="32" height="32" />
        </div>
    </div>
</div>
* {box-sizing: border-box;}
body {padding: 16px}
.form {
    width: 100%;
    display: flex;
    align-items: center;
    flex-direction: column;
    margin-bottom: 32px;
    margin-top: 16px;
}
.form p {
    width: fit-content;
}

.emojis {
    display: flex;
}
.emoji {
    cursor: pointer;
    margin: 10px;
    transition: all .2s ease;
    filter: grayscale(0.95);
}
.emoji:hover {
    scale: 1.3;
    filter: grayscale(0);
}

Eventを送信する

今回はイベントについて詳しく書かないので、詳しく知りたい場合は公式ドキュメントを参照してください

それと先ほどのコードを組み合わせて書くと次のようになります

const elements = document.querySelectorAll(".emoji");
const form = document.querySelector(".form");
const send = (element) => {
    const score = Number(element.attributes.score.nodeValue);
    gtag("event", `s_${score}`);
};
elements.forEach(element => {
    element.addEventListener("click", ()=> {
        send(element);
        form.innerHTML = `
        <p>貴重なご意見ありがとうございます</p>
        `;
    })
});
<div class="form">
    <p>このドキュメントどう?</p>
    <div class="emojis">
        <div class="emoji" score="0">
            <img src="/emoji/1f62d.svg" alt="emoji" width="32" height="32" />
        </div>
        <div class="emoji" score="1">
            <img src="/emoji/1f615.svg" alt="emoji" width="32" height="32" />
        </div>
        <div class="emoji" score="2">
            <img src="/emoji/1f600.svg" alt="emoji" width="32" height="32" />
        </div>
        <div class="emoji" score="3">
            <img src="/emoji/1f60d.svg" alt="emoji" width="32" height="32" />
        </div>
    </div>
</div>
* {box-sizing: border-box;}
body {padding: 16px}
.form {
    width: 100%;
    display: flex;
    align-items: center;
    flex-direction: column;
    margin-bottom: 32px;
    margin-top: 16px;
}
.form p {
    width: fit-content;
}

.emojis {
    display: flex;
}
.emoji {
    cursor: pointer;
    margin: 10px;
    transition: all .2s ease;
    filter: grayscale(0.95);
}
.emoji:hover {
    scale: 1.3;
    filter: grayscale(0);
}

これで完成ですがこれだと少し物足りないのでGoogle Analyticsでの確認方法も書きます

Eventを確認する

まず探索に移動し

Google-Analyticsの画面

新規作成を押します、新規に作成する必要はありませんが今回は分かりやすいように作成しています

Google-Analyticsの画面

作成したらイベント名ページロケーションディメンションを追加します

Google-Analyticsの画面

同様にイベント数指標も追加し

Google-Analyticsの画面

行にページロケーションディメンション、列にイベント名ディメンション、値にイベント数指標を指定し、フィールターにイベント名の先頭がs_と一致にすれば

Google-Analyticsの画面

終わりです

Google-Analyticsの画面

Next.jsでの実装

今回はnextjs-google-analyticsを使います

install

$ npm i nextjs-google-analytics

_app.tsx

import type { AppProps } from 'next/app';
import { GoogleAnalytics } from 'nextjs-google-analytics';

function MyApp({ Component, pageProps }: AppProps) {
    return (
        <>
            <GoogleAnalytics gaMeasurementId='G-XXXXXXXXXX' trackPageViews />
            <Component {...pageProps} />
        </>
    );
}

export default MyApp

component.tsx

import { useState } from "react"
import { event } from "nextjs-google-analytics";
import Image from "next/image";
import styles from "./style.module.scss"

const scores = [
    {
        emoji: "/emoji/1f62d.svg",
        score: 0
    },
    {
        emoji: "/emoji/1f615.svg",
        score: 1
    },
    {
        emoji: "/emoji/1f600.svg",
        score: 2
    },
    {
        emoji: "/emoji/1f60d.svg",
        score: 3
    }
] 

const Send = (score: number) => {
    event(`s_${score}`)
}

const Form = ({text = "このドキュメントどう?"}:{
    text?: string
}) => {
    const [now, setNow] = useState(-1)
    if(now != -1)
        return <div className={styles.form}>
            <p>貴重なご意見ありがとうございます</p>
        </div>
    return <div className={styles.form}>
        <p>{text}</p>
        <div className={styles.emojis}>
            {scores.map((data, i)=> <div key={i} onClick={()=> {
                setNow(i)
                Send(data.score)
            }} className={styles.emoji}>
                <Image src={data.emoji} alt="emoji" width={32} height={32} />
            </div>)}
        </div>
    </div>
}
export default Form

style.module.scss

.form {
    width: 100%;
    display: flex;
    align-items: center;
    flex-direction: column;
    margin-bottom: 32px;
    margin-top: 16px;
    p {
        width: fit-content;
    }
}

.emojis {
    display: flex;
}
.emoji {
    cursor: pointer;
    margin: 10px;
    transition: all .2s ease;
    filter: grayscale(0.95);
    &:hover {
        scale: 1.3;
        filter: grayscale(0);
    }
}

このドキュメントどう?

emoji
emoji
emoji
emoji