SaaS Boilerplate เป็นเทมเพลตที่ทรงพลังและปรับแต่งได้อย่างเต็มที่เพื่อเริ่มต้นแอปพลิเคชัน SaaS ของคุณ สร้างด้วย Next.js และ Tailwind CSS และส่วนประกอบ UI แบบโมดูลาร์ของ Shadcn UI เทมเพลต SaaS ของ Next.js นี้ช่วยให้คุณสร้างและเปิดใช้ SaaS ได้อย่างรวดเร็วโดยใช้ความพยายามเพียงเล็กน้อย
เต็มไปด้วยคุณสมบัติที่สำคัญ เช่น การรับรองความถูกต้อง ในตัว , ผู้เช่าหลายราย พร้อมการสนับสนุนทีม บทบาทและการอนุญาต , ฐานข้อมูล, I18n (การทำให้เป็นสากล), หน้า Landing Page, แดชบอร์ดผู้ใช้, การจัดการแบบฟอร์ม, การเพิ่มประสิทธิภาพ SEO, การบันทึก, การรายงานข้อผิดพลาดด้วย Sentry, การทดสอบ, การปรับใช้ , การตรวจสอบ และ การเลียนแบบผู้ใช้ เทมเพลต SaaS นี้มอบทุกสิ่งที่คุณต้องการในการเริ่มต้น
ออกแบบโดยคำนึงถึงนักพัฒนา ชุดเริ่มต้น Next.js นี้ใช้ TypeScript เพื่อความปลอดภัยในการพิมพ์และผสานรวม ESLint เพื่อรักษาคุณภาพของโค้ด พร้อมด้วย Prettier เพื่อการจัดรูปแบบโค้ดที่สอดคล้องกัน ชุดการทดสอบจะรวม Vitest และ React Testing Library เพื่อการทดสอบหน่วยที่มีประสิทธิภาพ ในขณะที่ Playwright จัดการการผสานรวมและการทดสอบ E2E การบูรณาการและการปรับใช้อย่างต่อเนื่องได้รับการจัดการผ่าน GitHub Actions สำหรับการจัดการผู้ใช้ การรับรองความถูกต้องจะได้รับการจัดการโดยเสมียน สำหรับการดำเนินการฐานข้อมูลนั้นจะใช้ Drizzle ORM สำหรับการจัดการฐานข้อมูลประเภทที่ปลอดภัยในฐานข้อมูลยอดนิยม เช่น PostgreSQL, SQLite และ MySQL
ไม่ว่าคุณกำลังสร้างแอป SaaS ใหม่หรือกำลังมองหา เทมเพลต SaaS ที่ยืดหยุ่นและพร้อมสำหรับการผลิต ต้นแบบนี้ก็พร้อมช่วยคุณแล้ว ชุดเริ่มต้นแบบโอเพ่นซอร์สฟรีนี้มีทุกสิ่งที่คุณต้องการเพื่อเร่งการพัฒนาและขยายขนาดผลิตภัณฑ์ของคุณได้อย่างง่ายดาย
โคลนโปรเจ็กต์นี้และใช้เพื่อสร้าง SaaS ของคุณเอง คุณสามารถตรวจสอบการสาธิตสดได้ที่ SaaS Boilerplate ซึ่งเป็นการสาธิตที่มีการตรวจสอบสิทธิ์ที่ใช้งานได้และระบบหลายผู้เช่า
เพิ่มโลโก้ของคุณที่นี่ |
การสาธิตสด: SaaS Boilerplate
หน้า Landing Page | แดชบอร์ดผู้ใช้ |
---|---|
การบริหารทีม | โปรไฟล์ผู้ใช้ |
---|---|
ลงทะเบียน | เข้าสู่ระบบ |
---|---|
หน้า Landing Page พร้อมโหมดมืด (เวอร์ชัน Pro) | แดชบอร์ดผู้ใช้พร้อมโหมดมืด (เวอร์ชัน Pro) |
---|---|
แดชบอร์ดผู้ใช้พร้อมแถบด้านข้าง (เวอร์ชัน Pro) |
---|
ประสบการณ์ของนักพัฒนาต้องมาก่อน โครงสร้างโค้ดที่ยืดหยุ่นอย่างยิ่ง และเก็บเฉพาะสิ่งที่คุณต้องการเท่านั้น:
@
คุณสมบัติในตัวจาก Next.js:
รันคำสั่งต่อไปนี้บนสภาพแวดล้อมภายในเครื่องของคุณ:
git clone --depth=1 https://github.com/ixartz/SaaS-Boilerplate.git my-project-name
cd my-project-name
npm install
สำหรับข้อมูลของคุณ การขึ้นต่อกันทั้งหมดจะได้รับการอัปเดตทุกเดือน
จากนั้น คุณสามารถรันโปรเจ็กต์ภายในเครื่องในโหมดการพัฒนาด้วยการรีโหลดแบบสดโดยดำเนินการ:
npm run dev
เปิด http://localhost:3000 ด้วยเบราว์เซอร์ที่คุณชื่นชอบเพื่อดูโครงการของคุณ
สร้างบัญชีเสมียนที่ Clerk.com และสร้างแอปพลิเคชันใหม่ในแดชบอร์ดเสมียน จากนั้น คัดลอกค่าของ NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY
และ CLERK_SECRET_KEY
ลงในไฟล์ .env.local
(ซึ่ง Git ไม่ได้ติดตาม):
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_pub_key
CLERK_SECRET_KEY=your_clerk_secret_key
ในแดชบอร์ดพนักงานของคุณ คุณยังต้อง Enable Organization
โดยไปที่ Organization management
> Settings
> Enable organization
ตอนนี้คุณมีระบบการตรวจสอบสิทธิ์ที่ทำงานได้เต็มรูปแบบด้วย Next.js: ลงทะเบียน ลงชื่อเข้าใช้ ออกจากระบบ ลืมรหัสผ่าน รีเซ็ตรหัสผ่าน อัปเดตโปรไฟล์ อัปเดตรหัสผ่าน อัปเดตอีเมล ลบบัญชี และอีกมากมาย
โปรเจ็กต์นี้ใช้ DrizzleORM ซึ่งเป็น ORM ที่ปลอดภัยซึ่งเข้ากันได้กับฐานข้อมูล PostgreSQL, SQLite และ MySQL ตามค่าเริ่มต้น โปรเจ็กต์ได้รับการตั้งค่าให้ทำงานได้อย่างราบรื่นกับ PostgreSQL และคุณสามารถเลือกผู้ให้บริการฐานข้อมูล PostgreSQL ใดก็ได้ได้อย่างง่ายดาย
สำหรับการแปล โปรเจ็กต์ใช้ next-intl
ร่วมกับ Crowdin ในฐานะนักพัฒนา คุณจะต้องดูแลเวอร์ชันภาษาอังกฤษ (หรือภาษาเริ่มต้นอื่น) เท่านั้น การแปลภาษาอื่นจะถูกสร้างขึ้นและจัดการโดย Crowdin โดยอัตโนมัติ คุณสามารถใช้ Crowdin เพื่อทำงานร่วมกับทีมแปลของคุณ หรือแปลข้อความด้วยตัวเองโดยใช้การแปลด้วยเครื่อง
หากต้องการตั้งค่าการแปล (i18n) ให้สร้างบัญชีที่ Crowdin.com และสร้างโปรเจ็กต์ใหม่ ในโปรเจ็กต์ที่สร้างขึ้นใหม่ คุณจะสามารถค้นหารหัสโปรเจ็กต์ได้ คุณจะต้องสร้างโทเค็นการเข้าถึงส่วนบุคคลใหม่โดยไปที่การตั้งค่าบัญชี > API จากนั้น ใน GitHub Actions คุณจะต้องกำหนดตัวแปรสภาพแวดล้อมต่อไปนี้: CROWDIN_PROJECT_ID
และ CROWDIN_PERSONAL_TOKEN
หลังจากกำหนดตัวแปรสภาพแวดล้อมใน GitHub Actions แล้ว ไฟล์การแปลเป็นภาษาท้องถิ่นของคุณจะถูกซิงโครไนซ์กับ Crowdin ทุกครั้งที่คุณส่งคอมมิตใหม่ไปยังสาขา main
.
├── README.md # README file
├── .github # GitHub folder
├── .husky # Husky configuration
├── .storybook # Storybook folder
├── .vscode # VSCode configuration
├── migrations # Database migrations
├── public # Public assets folder
├── scripts # Scripts folder
├── src
│ ├── app # Next JS App (App Router)
│ ├── components # Reusable components
│ ├── features # Components specific to a feature
│ ├── libs # 3rd party libraries configuration
│ ├── locales # Locales folder (i18n messages)
│ ├── models # Database models
│ ├── styles # Styles folder
│ ├── templates # Templates folder
│ ├── types # Type definitions
│ └── utils # Utilities folder
├── tests
│ ├── e2e # E2E tests, also includes Monitoring as Code
│ └── integration # Integration tests
├── tailwind.config.js # Tailwind CSS configuration
└── tsconfig.json # TypeScript configuration
คุณสามารถกำหนดค่า Next.js SaaS Boilerplate ได้อย่างง่ายดายโดยค้นหา FIXME:
ในโปรเจ็กต์ทั้งหมดเพื่อทำการปรับแต่งอย่างรวดเร็ว นี่คือไฟล์ที่สำคัญที่สุดบางส่วนที่ต้องปรับแต่ง:
public/apple-touch-icon.png
, public/favicon.ico
, public/favicon-16x16.png
และ public/favicon-32x32.png
: favicon เว็บไซต์ของคุณsrc/utils/AppConfig.ts
: ไฟล์คอนฟิกูเรชันsrc/templates/BaseTemplate.tsx
: ธีมเริ่มต้นnext.config.mjs
: การกำหนดค่า Next.js.env
: ตัวแปรสภาพแวดล้อมเริ่มต้นคุณสามารถเข้าถึงซอร์สโค้ดได้อย่างเต็มที่เพื่อการปรับแต่งเพิ่มเติม รหัสที่ให้มาเป็นเพียงตัวอย่างเพื่อช่วยคุณในการเริ่มต้นโครงการ ท้องฟ้ามีขีดจำกัด
ในซอร์สโค้ด คุณยังจะพบความคิดเห็น PRO
ที่ระบุโค้ดที่มีเฉพาะในเวอร์ชัน PRO เท่านั้น คุณสามารถลบหรือแทนที่โค้ดนี้ด้วยการนำไปใช้งานของคุณเองได้อย่างง่ายดาย
หากต้องการแก้ไขสคีมาฐานข้อมูลในโปรเจ็กต์ คุณสามารถอัปเดตไฟล์สคีมาซึ่งอยู่ที่ ./src/models/Schema.ts
ไฟล์นี้กำหนดโครงสร้างของตารางฐานข้อมูลของคุณโดยใช้ไลบรารี Drizzle ORM
หลังจากทำการเปลี่ยนแปลงสคีมาแล้ว ให้สร้างการย้ายข้อมูลโดยการรันคำสั่งต่อไปนี้:
npm run db:generate
สิ่งนี้จะสร้างไฟล์การโยกย้ายที่สะท้อนถึงการเปลี่ยนแปลงสคีมาของคุณ การย้ายข้อมูลจะใช้โดยอัตโนมัติในระหว่างการโต้ตอบกับฐานข้อมูลครั้งถัดไป ดังนั้นจึงไม่จำเป็นต้องรันด้วยตนเองหรือรีสตาร์ทเซิร์ฟเวอร์ Next.js
โปรเจ็กต์นี้เป็นไปตามข้อกำหนด Conventional Commits ซึ่งหมายความว่าข้อความคอมมิตทั้งหมดจะต้องมีการจัดรูปแบบตามนั้น เพื่อช่วยคุณเขียนข้อความคอมมิต โปรเจ็กต์ใช้ Commitizen ซึ่งเป็น CLI แบบโต้ตอบที่จะแนะนำคุณตลอดกระบวนการคอมมิต หากต้องการใช้งานให้รันคำสั่งต่อไปนี้:
npm run commit
ข้อดีอย่างหนึ่งของการใช้ Conventional Commits คือความสามารถในการสร้างไฟล์ CHANGELOG
โดยอัตโนมัติ นอกจากนี้ยังช่วยให้เรากำหนดหมายเลขเวอร์ชันถัดไปโดยอัตโนมัติตามประเภทของการคอมมิตที่รวมอยู่ในรีลีส
โครงการนี้รวมเข้ากับ Stripe สำหรับการชำระค่าสมัครสมาชิก คุณต้องสร้างบัญชี Stripe และคุณต้องติดตั้ง Stripe CLI ด้วย หลังจากติดตั้ง Stripe CLI คุณจะต้องเข้าสู่ระบบโดยใช้ CLI:
stripe login
จากนั้น คุณสามารถรันคำสั่งต่อไปนี้เพื่อสร้างราคาใหม่:
npm run stripe:setup-price
หลังจากรันคำสั่ง คุณจะต้องคัดลอกรหัสราคาและวางใน src/utils/AppConfig.ts
โดยอัปเดตรหัสราคาที่มีอยู่ด้วยรหัสใหม่
ใน Stripe Dashboard คุณจะต้องกำหนดการตั้งค่าพอร์ทัลลูกค้าของคุณที่ https://dashboard.stripe.com/test/settings/billing/portal สิ่งสำคัญที่สุดคือคุณต้องบันทึกการตั้งค่า
ในไฟล์ .env
คุณต้องอัปเดต NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
ด้วยคีย์ Stripe Publishable ของคุณเอง คุณสามารถค้นหากุญแจได้ใน Stripe Dashboard จากนั้น คุณยังต้องสร้างไฟล์ใหม่ชื่อ .env.local
และเพิ่มตัวแปรสภาพแวดล้อมต่อไปนี้ในไฟล์ที่สร้างขึ้นใหม่:
STRIPE_SECRET_KEY=your_stripe_secret_key
STRIPE_WEBHOOK_SECRET=your_stripe_webhook_secret
คุณได้รับ STRIPE_SECRET_KEY
จาก Stripe Dashboard ของคุณ STRIPE_WEBHOOK_SECRET
ถูกสร้างขึ้นโดยการรันคำสั่งต่อไปนี้:
npm run dev
คุณจะพบความลับในการเซ็นชื่อ webhook ในเทอร์มินัลของคุณ คุณสามารถคัดลอกและวางลงในไฟล์ .env.local
ของคุณได้
การทดสอบหน่วยทั้งหมดจะอยู่ข้างซอร์สโค้ดในไดเร็กทอรีเดียวกัน ทำให้ค้นหาได้ง่ายขึ้น โปรเจ็กต์นี้ใช้ Vitest และ React Testing Library สำหรับการทดสอบหน่วย คุณสามารถรันการทดสอบด้วยคำสั่งต่อไปนี้:
npm run test
โปรเจ็กต์นี้ใช้ Playwright เพื่อบูรณาการและการทดสอบแบบ end-to-end (E2E) คุณสามารถรันการทดสอบด้วยคำสั่งต่อไปนี้:
npx playwright install # Only for the first time in a new environment
npm run test:e2e
ในสภาพแวดล้อมท้องถิ่น การทดสอบด้วยภาพจะถูกปิดใช้งาน และเทอร์มินัลจะแสดงข้อความ [percy] Percy is not running, disabling snapshots.
- ตามค่าเริ่มต้น การทดสอบด้วยภาพจะทำงานใน GitHub Actions เท่านั้น
โฟลเดอร์ App Router เข้ากันได้กับรันไทม์ Edge คุณสามารถเปิดใช้งานได้โดยเพิ่มบรรทัดต่อไปนี้ src/app/layouts.tsx
:
export const runtime = 'edge' ;
สำหรับข้อมูลของคุณ การย้ายฐานข้อมูลเข้ากันไม่ได้กับรันไทม์ Edge ดังนั้น คุณต้องปิดการใช้งานการย้ายข้อมูลอัตโนมัติใน src/libs/DB.ts
:
await migrate ( db , { migrationsFolder : './migrations' } ) ;
หลังจากปิดใช้งานแล้ว คุณจะต้องดำเนินการย้ายข้อมูลด้วยตนเองด้วย:
npm run db:migrate
คุณต้องรันคำสั่งทุกครั้งที่คุณต้องการอัพเดตสคีมาฐานข้อมูล
ในระหว่างกระบวนการสร้าง การย้ายฐานข้อมูลจะดำเนินการโดยอัตโนมัติ ดังนั้นจึงไม่จำเป็นต้องดำเนินการด้วยตนเอง อย่างไรก็ตาม คุณต้องกำหนด DATABASE_URL
ในตัวแปรสภาพแวดล้อมของคุณ
จากนั้น คุณสามารถสร้างบิลด์ที่ใช้งานจริงด้วย:
$ npm run build
มันสร้างโครงสร้างการผลิตที่เหมาะสมที่สุดของแผ่นสำเร็จรูป หากต้องการทดสอบบิลด์ที่สร้างขึ้น ให้รัน:
$ npm run start
คุณต้องกำหนดตัวแปรสภาพแวดล้อม CLERK_SECRET_KEY
โดยใช้รหัสของคุณเอง
คำสั่งนี้เริ่มต้นเซิร์ฟเวอร์ภายในเครื่องโดยใช้บิลด์ที่ใช้งานจริง ตอนนี้คุณสามารถเปิด http://localhost:3000 ในเบราว์เซอร์ที่คุณต้องการเพื่อดูผลลัพธ์ได้
โครงการใช้ Sentry เพื่อตรวจสอบข้อผิดพลาด ในสภาพแวดล้อมการพัฒนา ไม่จำเป็นต้องตั้งค่าเพิ่มเติม: NextJS SaaS Boilerplate ได้รับการกำหนดค่าไว้ล่วงหน้าเพื่อใช้ Sentry และ Spotlight (Sentry for Development) ข้อผิดพลาดทั้งหมดจะถูกส่งไปยังอินสแตนซ์ Spotlight ในพื้นที่ของคุณโดยอัตโนมัติ เพื่อให้คุณสัมผัสประสบการณ์ Sentry ในพื้นที่ได้
สำหรับสภาพแวดล้อมการใช้งานจริง คุณจะต้องสร้างบัญชี Sentry และโปรเจ็กต์ใหม่ จากนั้นใน next.config.mjs
คุณจะต้องอัปเดตแอตทริบิวต์ org
และ project
ในฟังก์ชัน withSentryConfig
นอกจากนี้ ให้เพิ่ม Sentry DSN ของคุณไปที่ sentry.client.config.ts
, sentry.edge.config.ts
และ sentry.server.config.ts
เทมเพลต SaaS ของ Next.js อาศัย Codecov สำหรับโซลูชันการรายงานการครอบคลุมโค้ด หากต้องการเปิดใช้งาน Codecov ให้สร้างบัญชี Codecov และเชื่อมต่อกับบัญชี GitHub ของคุณ พื้นที่เก็บข้อมูลของคุณควรปรากฏบนแดชบอร์ด Codecov ของคุณ เลือกที่เก็บที่ต้องการและคัดลอกโทเค็น ใน GitHub Actions ให้กำหนดตัวแปรสภาพแวดล้อม CODECOV_TOKEN
และวางโทเค็น
ตรวจสอบให้แน่ใจว่าได้สร้าง CODECOV_TOKEN
เป็นความลับของ GitHub Actions อย่าวางลงในซอร์สโค้ดของคุณโดยตรง
โครงการใช้ Pino.js ในการบันทึก ในสภาพแวดล้อมการพัฒนา บันทึกจะแสดงในคอนโซลตามค่าเริ่มต้น
สำหรับการผลิต โปรเจ็กต์ได้รวมเข้ากับ Better Stack แล้วเพื่อจัดการและสืบค้นบันทึกของคุณโดยใช้ SQL หากต้องการใช้ Better Stack คุณต้องสร้างบัญชี Better Stack และสร้างแหล่งที่มาใหม่: ไปที่ Better Stack Logs Dashboard > แหล่งที่มา > เชื่อมต่อแหล่งที่มา จากนั้น คุณจะต้องตั้งชื่อให้กับแหล่งที่มาของคุณและเลือก Node.js เป็นแพลตฟอร์ม
หลังจากสร้างแหล่งที่มา คุณจะสามารถดูและคัดลอกโทเค็นแหล่งที่มาของคุณได้ ในตัวแปรสภาพแวดล้อมของคุณ ให้วางโทเค็นลงในตัวแปร LOGTAIL_SOURCE_TOKEN
ขณะนี้ บันทึกทั้งหมดจะถูกส่งไปยัง Better Stack และนำเข้าโดยอัตโนมัติ
โปรเจ็กต์ใช้ Checkly เพื่อให้แน่ใจว่าสภาพแวดล้อมการผลิตของคุณพร้อมใช้งานอยู่เสมอ เป็นระยะๆ Checkly จะทำการทดสอบที่ลงท้ายด้วยนามสกุล *.check.e2e.ts
และแจ้งให้คุณทราบหากการทดสอบใดล้มเหลว นอกจากนี้ คุณยังมีความยืดหยุ่นในการดำเนินการทดสอบจากหลายสถานที่เพื่อให้แน่ใจว่าแอปพลิเคชันของคุณพร้อมใช้งานทั่วโลก
หากต้องการใช้ Checkly คุณต้องสร้างบัญชีบนเว็บไซต์ก่อน หลังจากสร้างบัญชีแล้ว ให้สร้างคีย์ API ใหม่ใน Checkly Dashboard และตั้งค่าตัวแปรสภาพแวดล้อม CHECKLY_API_KEY
ใน GitHub Actions นอกจากนี้ คุณจะต้องกำหนด CHECKLY_ACCOUNT_ID
ซึ่งสามารถพบได้ใน Checkly Dashboard ของคุณภายใต้การตั้งค่าผู้ใช้ > ทั่วไป
เพื่อให้การตั้งค่าเสร็จสมบูรณ์ ให้อัปเดตไฟล์ checkly.config.ts
ด้วยที่อยู่อีเมลและ URL ที่ใช้งานจริงของคุณเอง
Next.js SaaS Starter Kit มีตัววิเคราะห์บันเดิลในตัว สามารถใช้เพื่อวิเคราะห์ขนาดของชุด JavaScript ของคุณได้ ในการเริ่มต้น ให้รันคำสั่งต่อไปนี้:
npm run build-stats
เมื่อรันคำสั่งจะเป็นการเปิดหน้าต่างเบราว์เซอร์ใหม่พร้อมผลลัพธ์โดยอัตโนมัติ
โปรเจ็กต์ได้รับการกำหนดค่าด้วย Drizzle Studio เพื่อสำรวจฐานข้อมูลแล้ว คุณสามารถเรียกใช้คำสั่งต่อไปนี้เพื่อเปิดสตูดิโอฐานข้อมูล:
npm run db:studio
จากนั้น คุณสามารถเปิด https://local.drizzle.studio ด้วยเบราว์เซอร์ที่คุณชื่นชอบเพื่อสำรวจฐานข้อมูลของคุณ
หากคุณเป็นผู้ใช้ VSCode คุณสามารถทำงานร่วมกับ VSCode ได้ดียิ่งขึ้นโดยการติดตั้งส่วนขยายที่แนะนำใน .vscode/extension.json
รหัสเริ่มต้นมาพร้อมกับการตั้งค่าเพื่อการใช้งานร่วมกับ VSCode ได้อย่างราบรื่น นอกจากนี้ การกำหนดค่าการแก้ไขข้อบกพร่องยังมีไว้สำหรับประสบการณ์การแก้ไขข้อบกพร่องส่วนหน้าและส่วนหลังอีกด้วย
เมื่อติดตั้งปลั๊กอินใน VSCode ของคุณ ESLint และ Prettier จะสามารถแก้ไขโค้ดและแสดงข้อผิดพลาดได้โดยอัตโนมัติ เช่นเดียวกับการทดสอบ: คุณสามารถติดตั้งส่วนขยาย VSCode Vitest เพื่อรันการทดสอบของคุณโดยอัตโนมัติ และยังแสดงความครอบคลุมของโค้ดในบริบทอีกด้วย
เคล็ดลับสำหรับมือโปร: หากคุณต้องการการตรวจสอบโปรเจ็กต์แบบกว้างด้วย TypeScript คุณสามารถรันบิลด์ด้วย Cmd + Shift + B บน Mac
เรายินดีให้ทุกคนมีส่วนร่วมในโครงการนี้ อย่าลังเลที่จะเปิดปัญหาหากคุณมีคำถามหรือพบข้อบกพร่อง เปิดรับข้อเสนอแนะและการปรับปรุงอย่างเต็มที่
ได้รับอนุญาตภายใต้ใบอนุญาต MIT ลิขสิทธิ์ © 2024
ดูใบอนุญาตสำหรับข้อมูลเพิ่มเติม
เพิ่มโลโก้ของคุณที่นี่ |
ทำด้วย♥โดย CreativeDesignsGuru
กำลังมองหาต้นแบบที่กำหนดเองเพื่อเริ่มต้นโปรเจ็กต์ของคุณอยู่ใช่ไหม? ฉันยินดีที่จะหารือเกี่ยวกับวิธีที่ฉันจะช่วยคุณสร้างมันขึ้นมา โปรดติดต่อได้ตลอดเวลาที่ [email protected]!