A modern, multilingual restaurant website built with Next.js 14, TypeScript, Sanity CMS, Shadcn and Tailwind CSS. The website features a full menu system, lunch specials, news section, and integrated content management.
- Multilingual Support: Swedish and English language support with next-intl
- Content Management: Sanity CMS with separate development and production environments
- Restaurant Menu: Dynamic menu with categories, subcategories, and wine selection
- Lunch System: Lunch specials management
- News/Blog: News and updates section
- Animations: Smooth animations using Framer Motion and GSAP
- Contact Form: Email integration using Resend
- Responsive Design: Mobile-first responsive design
- SEO Optimized: Built with Next.js 14 App Router for optimal performance
- Framework: Next.js 14 (App Router)
- Language: TypeScript
- CMS: Sanity v3
- Styling: Tailwind CSS + Shadcn UI
- Animations: Framer Motion, GSAP
- Internationalization: next-intl
- Forms: React Hook Form + Zod validation
- Email: Resend
- Node.js 18+ and npm
- Sanity account (for CMS)
- Resend API key (for contact form)
The project uses a secure environment variable setup:
.env.local- Contains sensitive API keys.env.development- Development-specific public settings.env.production- Production-specific public settings
- Copy the example file to create your local environment:
cp .env.local.example .env.local- Create environment-specific files:
# Create development environment file
echo "NEXT_PUBLIC_SANITY_DATASET=development
NEXT_PUBLIC_SANITY_PROJECT_ID=zax24rdo
NEXT_PUBLIC_VERCEL_URL=localhost:3000" > .env.development
# Create production environment file
echo "NEXT_PUBLIC_SANITY_DATASET=production
NEXT_PUBLIC_SANITY_PROJECT_ID=zax24rdo
NEXT_PUBLIC_VERCEL_URL=www.palermo-uppsala.se" > .env.production- Fill in your API keys in
.env.local:
# Sensitive API keys - DO NOT COMMIT
RESEND_API_KEY=your_resend_api_key
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=your_google_maps_key
INSTAGRAM_KEY=your_instagram_key
SANITY_API_READ_TOKEN=your_sanity_token
# Google Analytics (production only)
NEXT_PUBLIC_GA_MEASUREMENT_ID=your_ga_id- Next.js automatically loads the correct files based on environment:
- Development:
.env.local+.env.development - Production:
.env.local+.env.production
- Development:
.env.localtakes precedence over other environment files- Sanity dataset is automatically set:
- Development:
NEXT_PUBLIC_SANITY_DATASET=development - Production:
NEXT_PUBLIC_SANITY_DATASET=production
- Development:
- Never commit API keys, tokens, or sensitive environment variables to the repository
- All environment files are kept local for security
- Clone the repository:
git clone [email protected]:nerotheman/palermo.git
cd palermo- Install dependencies:
npm install-
Set up environment variables (see above)
-
Run the development server:
npm run dev- Open http://localhost:3000 in your browser
npm run dev- Start development servernpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLintnpm run typecheck- Run TypeScript type checking
palermo/
├── src/
│ ├── app/
│ │ ├── (admin)/ # Sanity Studio routes
│ │ └── (user)/ # Public website routes
│ ├── components/ # React components
│ ├── lib/ # Utility functions
│ ├── types/ # TypeScript types
│ └── providers/ # React providers
├── sanity/ # Sanity configuration
│ ├── schemas/ # Content schemas
│ └── lib/ # Sanity utilities
├── messages/ # i18n translation files
├── public/ # Static assets
└── ...config files
The site supports Swedish (default) and English. Language switching is handled by next-intl with locale-specific routing:
/- Swedish homepage/en- English homepage/meny- Swedish menu/en/menu- English menu
Two Sanity datasets are configured:
- Development: For testing and development at
/studio/development - Production: For live content at
/studio/production
- Categories and subcategories for food items
- Separate wine list with categories
- Price display and descriptions
- Multilingual support for all menu items
- Page transitions with Framer Motion
- Text animations with custom MaskText component
- Scroll-triggered animations with FadeUp component
- Image galleries with carousel functionality
- Push your code to GitHub
- Import project to Vercel
- Add environment variables in Vercel dashboard
- Deploy
Build the project:
npm run buildThe build output will be in .next directory. Follow your platform's Next.js deployment guide.
- Development:
https://palermo-uppsala/studio/development - Production:
https://palermo-uppsala/studio/production
-
Pages
- Home Page
- About Page
- Lunch Page
-
Menu
- Food Items
- Wine Items
- Categories
- Subcategories
-
Other
- News/Blog posts
- Contact information
- ES modules with destructured imports
- TypeScript for all files (avoid
anytype) - Server components by default
- Client components only when needed (marked with
"use client") - Conventional commits in English
- Create a feature branch
- Make your changes
- Run type checking:
npm run typecheck - Test in both Swedish and English locales
- Check responsive design
- Build before committing:
npm run build - Commit with conventional commits format:
type: description
This project is private and proprietary.
For issues or questions, please contact the development team.