Erstellen einer Portfolio-Website von Grund auf mit NextJS, TailwindCSS und Metricalp (2024)
Portfolio-Websites sind unerlässlich, um Ihre Arbeit zu präsentieren und potenzielle Kunden zu gewinnen. In diesem Beitrag werden wir eine Portfolio-Website von Grund auf mit NextJS 14, TailwindCSS und Metricalp erstellen. Wir werden alles abdecken, um die Website einzurichten und wie Sie Metricalp nutzen können, um Ihre Conversions zu steigern.
Einführung
In diesem Beitrag erstellen wir eine Portfolio-Website mit NextJS, TailwindCSS und Metricalp. Wir werden auch behandeln, wie man Benutzerverhalten verfolgt und datengetriebene Entscheidungen mit Metricalp trifft, die dein persönliches Wachstum fördern können. Die Website wird zwei Seiten haben: eine Startseite und eine Projektseite. Auf der Startseite können die Besucher ihre E-Mail-Adressen hinterlassen, mit denen wir sie kontaktieren können. Außerdem sehen sie auf der Projektseite unsere neuesten Projekte und können diese entdecken. Lass uns mit einem Blick auf die finale Ansicht beginnen 🚀
Okay, genug geredet, lass uns loslegen und es bauen 🚀
Projekt einrichten
Zuerst müssen wir ein neues NextJS-Projekt erstellen:
npx create-next-app@latest
Dank der NextJS-Beitragenden und dem Team haben sie einen großartigen CLI-Installer. Er fragt nach deinen Vorlieben und richtet das Projekt ein.
Hier sind alle Einstellungen, die ich beim Bootstrapping dieses Projekts ausgewählt habe:
Wir haben TailwindCSS und TypeScript ausgewählt, und der CLI installiert alle Abhängigkeiten und richtet das Projekt für uns ein.
Wir werden Metricalp zusätzlich installieren, um den Installationsprozess abzuschließen:
npm install metricalp
Wir erstellen einige Ordner/Dateien. Ich möchte das endgültige Aussehen der Projektstruktur teilen, die wir unten erläutern werden.
Wir haben gesagt, dass wir eine Startseite mit einem E-Mail-Formular und eine Projektseite haben. Sagen wir, wir möchten zwei Dinge mit Metricalp erfassen: submit_email, das jedes Mal ausgelöst wird, wenn ein Besucher auf den Senden-Button auf der Startseite klickt, und view_project_details, das jedes Mal ausgelöst wird, wenn ein Besucher auf den Detail-Button eines Projekts auf der Projektseite klickt. Diese Metriken können uns helfen zu verstehen, welches Projekt mehr Aufmerksamkeit von Besuchern erhält. Oder noch besser, wir können sehen, welche Besucher aus welchem Land/Browser mehr Interesse an welchem Projekt haben. Dies kann definitiv unsere Marketingstrategie beeinflussen. Lass uns das noch verrückter machen. Dies ist nur eine grundlegende Portfolio-Website, also haben wir keine Datenbank/Backend usw. Wie sammeln wir also E-Mails? Oh, Moment. Wir sammeln submit_email Ereignisse und in Metricalp kannst du benutzerdefinierte Eigenschaften an Ereignisse anhängen. Was wäre, wenn wir das ausgefüllte Texteingabefeld (E-Mail) an die submit_email Ereignisse anhängen? Dann verwenden wir Metricalp nicht nur als Analytik-Anbieter, sondern auch als einfache Datenbank? Wow, das ist großartig. Ja, das wissen wir. Dies ist die Schönheit von Metricalp, es gibt Millionen Nutzungsszenarien.
Okay, schauen wir uns ein paar Codes an. Lass uns das beste und einfachste Portfolio erstellen und unsere potenziellen Kunden erreichen.
Lass uns einen utils-Ordner im src-Ordner erstellen. Darin werden sich zwei Dateien befinden. Eine ist metricalp-events.ts und die andere ist constants.ts
src/utils/metricalp-events.ts Datei:
export const MetricalpEvents = {
SubmitEmail: 'submit_email',
ViewProjectDetails: 'view_project_details',
};
src/utils/constants.ts Datei:
export const METRICALP_TID = 'mam48'; // Ersetze durch deine Metricalp TID
Nun richten wir Metricalp ein und erstellen unser Hauptlayout. Bearbeite die Datei im Pfad und Namen src/app/layout.tsx:
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import './globals.css';
import { MetricalpReactProvider } from '@metricalp/react';
import Link from 'next/link';
import { METRICALP_TID } from '@/utils/constants';
const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
title: 'Melanie | Full-stack Developer',
description:
'Ich bin Melanie, eine Full-stack Entwicklerin mit einer Leidenschaft für den Aufbau schöner und funktionaler Websites.',
};
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html lang="en">
<body className={inter.className}>
<MetricalpReactProvider allowLocalhost tid={METRICALP_TID}>
<div className="h-full p-4 md:p-0 my-4">
<div className="w-full container mx-auto">
<div className="w-full flex items-center justify-between">
<a
className="flex items-center text-indigo-400 no-underline hover:no-underline font-bold text-2xl lg:text-4xl"
href="#"
>
<span className="bg-clip-text text-transparent bg-gradient-to-r from-green-400 via-pink-500 to-purple-500">
Melanie‘s
</span>
</a>
<div className="flex w-1/2 justify-end content-center space-x-4">
<Link href="/">
<span className="bg-clip-text text-lg text-transparent bg-gradient-to-r from-green-400 via-pink-500 to-purple-500">
Home
</span>
</Link>
<Link href="/projects">
<span className="bg-clip-text text-lg text-transparent bg-gradient-to-r from-green-400 via-pink-500 to-purple-500">
Projekte
</span>
</Link>
</div>
</div>
</div>
{children}
</div>
</MetricalpReactProvider>
</body>
</html>
);
}
Nun haben wir den Metricalp-Provider eingerichtet und wickeln unsere gesamte Anwendung damit ein. Wir verwenden auch TailwindCSS-Klassen, um unser Layout schöner zu gestalten. Wir verwenden die Schriftart Inter von Google Fonts. Wir nutzen auch die NextJS-Metadatenfunktion, um den Titel und die Beschreibung unserer Website festzulegen. Außerdem verwenden wir die Link-Komponente von NextJS, um zwischen den Seiten zu navigieren.
Wir haben eine obere Navigationsleiste mit einem Logo (als Text) links und zwei Navigationslinks zur Startseite und zur Projektseite rechts.
Wir verwenden die neueste Version von NextJS, sodass es Server- und Client-Komponenten gibt. Grundsätzlich sind interaktive Komponenten Client-Komponenten, und alle anderen sind Server-Komponenten. Lass uns mit der einfachsten beginnen. Erstelle eine Datei im Pfad und Namen src/components/shared/Button.tsx
'use client';
import { ReactNode } from 'react';
type Props = {
content: ReactNode;
onClick: () => void;
};
export const Button = ({ content, onClick }: Props) => {
return (
<button
onClick={onClick}
className="bg-gradient-to-r from-purple-800 to-green-500 hover:from-pink-500 hover:to-green-500 text-white font-bold py-2 px-4 rounded focus:ring transform transition hover:scale-105 duration-300 ease-in-out"
type="button"
>
{content}
</button>
);
};
Es beginnt mit 'use client', weil es eine Funktion als Prop (onClick) übernimmt/weitergibt. Ansonsten ist es nur ein einfacher Button. Um jedoch ein schickes Aussehen zu haben, haben wir Tailwind CSS-Klassen verwendet, die unserem Button eine gute Gradient-Ansicht verleihen. Zuletzt nehmen wir den Inhalt als ReactNode an, was bedeutet, dass es sich um einfachen Text oder eine React-Komponente handeln kann, was unseren Button anpassbarer macht. Dies ist unsere grundlegende Button-Komponente, daher befindet sie sich im shared-Ordner. Andere Stellen verwenden diesen Button mit Anpassung.
Okay, erstellen wir das Mail-Submit-Formular, das auf unserer Startseite platziert wird. Erstelle eine Datei im Pfad und Namen src/components/route-specific/homepage/MailSubmitForm.tsx:
'use client';
import { Button } from '@/components/shared/Button';
import { MetricalpEvents } from '@/utils/metricalp-events';
import { metricalpEvent } from '@metricalp/react';
import { useState } from 'react';
export const MailSubmitForm = () => {
const [email, setEmail] = useState('');
return (
<form className="bg-gray-900 opacity-75 w-full shadow-lg rounded-lg px-8 pt-6 pb-8 mb-4">
<div className="mb-4">
<label
className="block text-blue-300 py-2 font-bold mb-2"
htmlFor="emailaddress"
>
Hinterlassen Sie Ihre E-Mail-Adresse, um Kontakt aufzunehmen
</label>
<input
className="shadow appearance-none border rounded w-full p-3 text-gray-700 leading-tight focus:ring transform transition hover:scale-105 duration-300 ease-in-out"
id="emailaddress"
type="text"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="[email protected]"
/>
</div>
<div className="flex items-center justify-between pt-4">
<Button
content="Senden"
onClick={() => {
metricalpEvent({ type: MetricalpEvents.SubmitEmail, email });
alert('Gesendet');
}}
/>
</div>
</form>
);
};
Wieder ist es eine Client-Komponente, weil sie interaktiv ist. Grundsätzlich gibt es ein Eingabefeld und einen Senden-Button (unsere Button-Komponente). Wenn der Benutzer auf Senden klickt, lösen wir ein Metricalp-Ereignis aus, Metricalp.SubmitEmail, und übergeben die E-Mail als Prop an dieses Ereignis.
Wir haben den eingegebenen Text im Zustand gehalten und mit TailwindCSS-Klassen erneut gestylt.
Jetzt sehen wir uns unsere letzte Client-Komponente an, src/components/route-specific/projects/ProjectDetailsButton.tsx:
'use client';
import { Button } from '@/components/shared/Button';
import { MetricalpEvents } from '@/utils/metricalp-events';
import { metricalpEvent } from '@metricalp/react';
type Props = {
projectTitle: string;
};
export const ProjectDetailsButton = ({ projectTitle }: Props) => {
return (
<Button
content="Details"
onClick={() => {
metricalpEvent({
type: MetricalpEvents.ViewProjectDetails,
projectTitle,
});
alert('Details');
}}
/>
);
};
Wann immer ein Besucher auf den Detail-Button eines Projekts klickt, lösen wir das Ereignis Metricalp.ViewProjectDetails aus und übergeben den Projekttitel als Prop. Dies ist ein einfaches Beispiel, aber du kannst diesem Ereignis mehr Props hinzufügen.
Okay, jetzt entwickeln wir die Startseite, was nicht schwer sein wird, da alle funktionalen Komponenten bereits fertig sind.
Bearbeite die Datei im Pfad und Namen src/app/page.tsx:
import { MailSubmitForm } from '@/components/route-specific/homepage/MailSubmitForm';
import Image from 'next/image';
export default function Home() {
return (
<div className="container pt-24 md:pt-36 mx-auto flex flex-wrap flex-col md:flex-row items-center">
<div className="flex flex-col w-full xl:w-2/5 justify-center lg:items-start overflow-y-hidden">
<h1 className="my-4 text-3xl md:text-5xl text-white opacity-75 font-bold leading-tight text-center md:text-left">
Hey, lass uns{' '}
<span className="bg-clip-text text-transparent bg-gradient-to-r from-green-400 via-pink-500 to-purple-500">
die Welt verändern
</span>{' '}
zusammen
</h1>
<p className="leading-normal text-base md:text-2xl mb-8 text-center md:text-left">
Ich bin Melanie, eine Full-stack Entwicklerin mit einer Leidenschaft
für den Aufbau schöner und funktionaler Websites.
</p>
<MailSubmitForm />
</div>
<div className="w-full xl:w-3/5 p-12 overflow-hidden">
<Image
className="mx-auto w-full md:w-4/5 transform -rotate-6 transition hover:scale-105 duration-700 ease-in-out hover:rotate-6"
src="/cover.png"
alt="Cover image"
width={1080}
height={1080}
/>
</div>
</div>
);
}
Wir haben unseren Hauptüberschriftstext, ein Titelbild und ein Mail-Submit-Formular. Dies ist eine Server-Komponente, also haben wir 'use client' nicht hinzugefügt. Wir haben erneut TailwindCSS-Klassen verwendet, um ein gutes Aussehen zu erzielen.
Jetzt gibt es nur noch eine Seite, die noch erstellt werden muss: die Projekte-Seite. Lass uns sie erstellen. Erstelle die Datei im Pfad und Namen src/app/projects/page.tsx:
import { ProjectDetailsButton } from '@/components/route-specific/projects/ProjectDetailsButton';
import Image from 'next/image';
const projects = [
{
title: 'ToDo App',
description: 'Eine einfache To-Do-App, die mit React Native erstellt wurde',
image: 'https://cdn.metricalp.com/web/assets/images/rn-app-example-1.png',
},
{
title: 'Metricalp Website',
description: 'Die Marketing-Website für Metricalp',
image: 'https://cdn.metricalp.com/web/assets/images/hero-v4-light.webp',
},
];
export default function Projects() {
return (
<div className="p-8 flex justify-center flex-col items-center space-y-8">
{projects.map((project) => (
<div
key={project.title}
className="block rounded-lg bg-white shadow-secondary-1 text-black"
>
<div className="relative overflow-hidden bg-cover bg-no-repeat max-h-96">
<Image
className="rounded-t-lg"
src={project.image}
width={800}
height={400}
alt={project.title}
/>
</div>
<div className="p-6 text-surface ">
<h5 className="mb-2 text-xl font-medium leading-tight">
{project.title}
</h5>
<p className="mb-4 text-base">{project.description}</p>
<ProjectDetailsButton projectTitle={project.title} />
</div>
</div>
))}
</div>
);
}
Wir haben ein Projektarray, das unsere Projekte enthält. Wir mappen dieses Array und erstellen eine Karte für jedes Projekt. Jede Karte hat ein Bild, einen Titel, eine Beschreibung und einen Detail-Button. Wenn der Benutzer auf den Detail-Button klickt, lösen wir das Ereignis Metricalp.ViewProjectDetails aus und übergeben den Projekttitel als Prop.
Einfach, oder? Wir haben eine gut aussehende, robuste und vollständig SEO-optimierte Portfolio-Website mit NextJS, TailwindCSS und Metricalp erstellt. Wir haben auch Metricalp-Ereignisse hinzugefügt, um Benutzerverhalten zu verfolgen und datengetriebene Entscheidungen zu treffen. Außerdem haben wir Metricalp als einfache Datenbank verwendet, um E-Mails zu sammeln. Dies ist nur ein einfaches Beispiel, du kannst mehr mit Metricalp tun. Du kannst jedes Benutzerverhalten verfolgen, du kannst alle gewünschten Daten sammeln. Du kannst deine Website personalisierter und benutzerfreundlicher machen. Du kannst deine Konversionen steigern. Du kannst deine potenziellen Kunden erreichen. Du kannst die Welt verändern. 🚀
Metricalp wird automatisch Besuche-Ereignisse hören, wie viele einzigartige Besucher aus welchen Ländern etc. Wir haben auch einige benutzerdefinierte Ereignisse hinzugefügt wie submit_email und view_project_details.
Für angehängte benutzerdefinierte Props haben wir Aliase verwendet wie E-Mail und Projekt-Titel. Wir müssen dies im Metricalp-Dashboard im Tracker-Einstellungen-Register - allgemeine Registerkarte konfigurieren. Lass es uns als letzten Schritt tun.
Nun haben wir die E-Mail als benutzerdefinierte Prop 1 Alias für das Ereignis submit_email und Projekt-Titel als benutzerdefinierte Prop 1 Alias für das Ereignis view_project_details eingestellt. Jetzt können wir diese benutzerdefinierten Props sicher im Metricalp-Dashboard auslösen und anzeigen.
Wir erfassen, wie viele Personen unser Portfolio besucht haben. Woher kommen sie, was ist ihr Betriebssystem, Browser, Gerät (Mobil oder Desktop) usw. Zusätzlich zu diesen Standard-Analyse-Daten erfassen wir, wie viele eindeutige Besucher uns ihre E-Mail hinterlassen haben. Noch besser ist, dass wir auch ihre E-Mails hier erfassen. Wir brauchen nicht einmal eine separate Datenbank. Verrückt und großartig. Außerdem erfassen wir alle Ereignisse von Projekt-Detail-Ansichten. Wir können sehen, welches Projekt mehr Aufmerksamkeit bekommt. Wir können sehen, welches Projekt mehr Aufmerksamkeit aus welchem Land, Browser, Gerät usw. bekommt. Dies kann unsere zukünftige Karriere, Marketingstrategie usw. beeinflussen. Dies ist die Macht von Metricalp 🚀 Wir sind stolz auf unser Produkt, dass es uns auf einfache Weise hilft, diese Ziele zu erreichen.
Aber hey, du hast den ganzen Artikel gelesen, wir sind auch stolz auf dich. Ich hoffe, du wirst die beste Portfolio-Website haben und deine potenziellen Kunden erreichen. Wenn du Fragen, Feedback oder etwas anderes hast, zögere nicht, uns zu kontaktieren. Wir sind immer hier, um dir zu helfen. 💜 🤝