Skip to content

Commit 3198122

Browse files
committed
Initial commit: Portfolio website with GitHub Pages deployment
0 parents  commit 3198122

38 files changed

+9071
-0
lines changed

.github/workflows/deploy.yml

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: "pages"
15+
cancel-in-progress: false
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: '20'
28+
cache: 'npm'
29+
30+
- name: Install dependencies
31+
run: npm ci
32+
33+
- name: Build project
34+
run: npm run build
35+
36+
- name: Setup Pages
37+
uses: actions/configure-pages@v4
38+
with:
39+
static_site_generator: next
40+
41+
- name: Upload artifact
42+
uses: actions/upload-pages-artifact@v3
43+
with:
44+
path: ./out
45+
46+
deploy:
47+
environment:
48+
name: github-pages
49+
url: ${{ steps.deployment.outputs.page_url }}
50+
runs-on: ubuntu-latest
51+
needs: build
52+
steps:
53+
- name: Deploy to GitHub Pages
54+
id: deployment
55+
uses: actions/deploy-pages@v4

.gitignore

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
2+
3+
# dependencies
4+
/node_modules
5+
/.pnp
6+
.pnp.*
7+
.yarn/*
8+
!.yarn/patches
9+
!.yarn/plugins
10+
!.yarn/releases
11+
!.yarn/versions
12+
13+
# testing
14+
/coverage
15+
16+
# next.js
17+
/.next/
18+
/out/
19+
20+
# production
21+
/build
22+
23+
# misc
24+
.DS_Store
25+
*.pem
26+
27+
# debug
28+
npm-debug.log*
29+
yarn-debug.log*
30+
yarn-error.log*
31+
.pnpm-debug.log*
32+
33+
# env files (can opt-in for committing if needed)
34+
.env*
35+
36+
# vercel
37+
.vercel
38+
39+
# typescript
40+
*.tsbuildinfo
41+
next-env.d.ts

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2025 Samet D.
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# Samet Dulger - Portfolio Website
2+
3+
Personal portfolio website showcasing Full Stack Developer skills and projects.
4+
5+
## 🌐 Live Site
6+
**https://sametdulger.dev**
7+
8+
## 🛠️ Technologies Used
9+
10+
### Frontend
11+
- **Next.js 15.3.3** - React framework
12+
- **React 19** - UI library
13+
- **TypeScript** - Type safety
14+
- **Tailwind CSS 3.4** - Styling framework
15+
16+
### Libraries & Dependencies
17+
- **Framer Motion 12.18.1** - Animations
18+
- **React Icons 5.5.0** - Icon components
19+
- **Lucide React** - Additional icons
20+
21+
### Development Tools
22+
- **ESLint 9** - Code linting
23+
- **PostCSS 8.5.6** - CSS processing
24+
- **Autoprefixer 10.4.21** - CSS vendor prefixes
25+
26+
### Deployment
27+
- **GitHub Pages** - Static hosting
28+
- **GitHub Actions** - CI/CD pipeline
29+
- **Custom Domain** - sametdulger.dev
30+
31+
## 📦 Installation
32+
33+
```bash
34+
# Clone repository
35+
git clone https://github.com/SametDulger/sametdulger.dev.git
36+
37+
# Install dependencies
38+
npm install
39+
40+
# Run development server
41+
npm run dev
42+
```
43+
44+
## 🚀 Build & Deploy
45+
46+
```bash
47+
# Build for production
48+
npm run build
49+
50+
# Deploy to GitHub Pages
51+
npm run deploy
52+
```
53+
54+
## 📋 Scripts
55+
56+
- `npm run dev` - Start development server
57+
- `npm run build` - Build for production
58+
- `npm run start` - Start production server
59+
- `npm run lint` - Run ESLint
60+
- `npm run export` - Export static files
61+
- `npm run deploy` - Deploy to GitHub Pages

eslint.config.mjs

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
import { dirname } from "path";
2+
import { fileURLToPath } from "url";
3+
import { FlatCompat } from "@eslint/eslintrc";
4+
5+
const __filename = fileURLToPath(import.meta.url);
6+
const __dirname = dirname(__filename);
7+
8+
const compat = new FlatCompat({
9+
baseDirectory: __dirname,
10+
});
11+
12+
const eslintConfig = [
13+
...compat.extends("next/core-web-vitals", "next/typescript"),
14+
{
15+
ignores: [
16+
".next/**/*",
17+
"out/**/*",
18+
"build/**/*",
19+
"dist/**/*",
20+
"node_modules/**/*",
21+
"*.config.js",
22+
"*.config.ts",
23+
".next/types/**/*",
24+
".next/static/**/*",
25+
],
26+
},
27+
{
28+
rules: {
29+
"@typescript-eslint/no-explicit-any": "off",
30+
"@typescript-eslint/no-unused-vars": "off",
31+
"@typescript-eslint/no-unsafe-function-type": "off",
32+
"@typescript-eslint/no-empty-object-type": "off",
33+
"@typescript-eslint/no-wrapper-object-types": "off",
34+
"@typescript-eslint/no-unused-expressions": "off",
35+
},
36+
},
37+
];
38+
39+
export default eslintConfig;

next.config.ts

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
import type { NextConfig } from "next";
2+
3+
const nextConfig: NextConfig = {
4+
// GitHub Pages static export - only in production
5+
...(process.env.NODE_ENV === 'production' && {
6+
output: 'export',
7+
trailingSlash: true,
8+
skipTrailingSlashRedirect: true,
9+
distDir: 'out',
10+
// Custom domain - no basePath/assetPrefix needed
11+
}),
12+
13+
// Security Headers
14+
async headers() {
15+
return [
16+
{
17+
source: '/(.*)',
18+
headers: [
19+
{
20+
key: 'X-Frame-Options',
21+
value: 'DENY'
22+
},
23+
{
24+
key: 'X-Content-Type-Options',
25+
value: 'nosniff'
26+
},
27+
{
28+
key: 'Referrer-Policy',
29+
value: 'origin-when-cross-origin'
30+
},
31+
{
32+
key: 'X-DNS-Prefetch-Control',
33+
value: 'on'
34+
},
35+
{
36+
key: 'Strict-Transport-Security',
37+
value: 'max-age=31536000; includeSubDomains'
38+
},
39+
{
40+
key: 'Permissions-Policy',
41+
value: 'camera=(), microphone=(), geolocation=()'
42+
}
43+
]
44+
}
45+
]
46+
},
47+
48+
// Performance optimizations
49+
compress: true,
50+
poweredByHeader: false,
51+
reactStrictMode: true,
52+
53+
// Compiler optimizations
54+
compiler: {
55+
removeConsole: process.env.NODE_ENV === 'production',
56+
},
57+
58+
// Image optimization
59+
images: {
60+
// Only unoptimize images in production for static export
61+
...(process.env.NODE_ENV === 'production' && { unoptimized: true }),
62+
formats: ['image/avif', 'image/webp'],
63+
deviceSizes: [640, 750, 828, 1080, 1200, 1920, 2048, 3840],
64+
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
65+
dangerouslyAllowSVG: true,
66+
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
67+
},
68+
69+
// Experimental features for better performance
70+
experimental: {
71+
optimizePackageImports: ['react-icons'],
72+
// 2025 Performance Features
73+
webVitalsAttribution: ['CLS', 'LCP', 'FCP', 'FID', 'TTFB', 'INP'],
74+
},
75+
76+
// Turbopack configuration (moved from experimental)
77+
turbopack: {
78+
rules: {
79+
'*.svg': {
80+
loaders: ['@svgr/webpack'],
81+
as: '*.js',
82+
},
83+
},
84+
},
85+
86+
// Bundle analyzer and optimization
87+
webpack: (config, { dev, isServer }) => {
88+
// Production optimizations
89+
if (!dev && !isServer) {
90+
config.optimization.splitChunks = {
91+
chunks: 'all',
92+
minSize: 20000,
93+
maxSize: 244000,
94+
cacheGroups: {
95+
vendor: {
96+
test: /[\\/]node_modules[\\/]/,
97+
name: 'vendors',
98+
chunks: 'all',
99+
priority: 10,
100+
},
101+
common: {
102+
name: 'common',
103+
minChunks: 2,
104+
chunks: 'all',
105+
priority: 5,
106+
enforce: true,
107+
},
108+
react: {
109+
test: /[\\/]node_modules[\\/](react|react-dom)[\\/]/,
110+
name: 'react',
111+
chunks: 'all',
112+
priority: 20,
113+
},
114+
icons: {
115+
test: /[\\/]node_modules[\\/]react-icons[\\/]/,
116+
name: 'icons',
117+
chunks: 'all',
118+
priority: 15,
119+
},
120+
motion: {
121+
test: /[\\/]node_modules[\\/]framer-motion[\\/]/,
122+
name: 'motion',
123+
chunks: 'all',
124+
priority: 12,
125+
},
126+
},
127+
};
128+
129+
// Tree shaking optimization
130+
config.optimization.usedExports = true;
131+
config.optimization.sideEffects = false;
132+
}
133+
return config;
134+
},
135+
};
136+
137+
export default nextConfig;

0 commit comments

Comments
 (0)