Compare commits

..

No commits in common. "d468ecca7485fbab512266910c14cca5daf45c2d" and "186bd3c2ccfc916ef63041ab323ac795caa3ebc7" have entirely different histories.

13 changed files with 255 additions and 386 deletions

View File

@ -1,28 +1,5 @@
# Strictly Server side Env variables
XAI_API_KEY=
UPSTASH_REDIS_REST_URL=
UPSTASH_REDIS_REST_TOKEN=
AVIATION_STACK_API_KEY=
SANDBOX_TEMPLATE_ID=
TMDB_API_KEY=
YT_ENDPOINT=
EXA_API_KEY=
TRIPADVISOR_API_KEY=
BLOB_READ_WRITE_TOKEN=
ELEVENLABS_API_KEY=
AZURE_TRANSLATOR_LOCATION=
AZURE_TRANSLATOR_KEY=
AZURE_RESOURCE_NAME=
AZURE_API_KEY=
MAPBOX_ACCESS_TOKEN=
FIRECRAWL_API_KEY=
ANTHROPIC_API_KEY=sk-ant-api****
TAVILY_API_KEY=tvly-****
OPENWEATHER_API_KEY=
E2B_API_KEY=e2b_****
GOOGLE_MAPS_API_KEY=
# Client side Env variables
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=
NEXT_PUBLIC_MAPBOX_TOKEN=
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=
GROQ_API_KEY=gsk_****
OPENWEATHER_API_KEY=***
E2B_API_KEY=e2b_****

View File

@ -1,4 +1,3 @@
import { serverEnv } from '@/env/server';
import { del, list, ListBlobResult } from '@vercel/blob';
import { NextRequest, NextResponse } from 'next/server';

View File

@ -1,6 +1,7 @@
import { NextResponse } from 'next/server';
import { generateObject } from 'ai';
import { z } from 'zod';
import { geolocation } from '@vercel/functions';
import { xai } from '@ai-sdk/xai';
export interface TrendingQuery {
@ -15,7 +16,7 @@ interface RedditPost {
};
}
async function fetchGoogleTrends(): Promise<TrendingQuery[]> {
async function fetchGoogleTrends(countryCode: string = 'US'): Promise<TrendingQuery[]> {
const fetchTrends = async (geo: string): Promise<TrendingQuery[]> => {
try {
const response = await fetch(`https://trends.google.com/trends/trendingsearches/daily/rss?geo=${geo}`, {
@ -61,7 +62,7 @@ async function fetchGoogleTrends(): Promise<TrendingQuery[]> {
}
};
const trends = await fetchTrends("US");
const trends = await fetchTrends(countryCode);
return [ ...trends];
}
@ -94,11 +95,11 @@ async function fetchRedditQuestions(): Promise<TrendingQuery[]> {
}
}
async function fetchFromMultipleSources() {
async function fetchFromMultipleSources(countryCode: string) {
const [googleTrends,
// redditQuestions
] = await Promise.all([
fetchGoogleTrends(),
fetchGoogleTrends(countryCode),
// fetchRedditQuestions(),
]);
@ -111,11 +112,11 @@ async function fetchFromMultipleSources() {
export async function GET(req: Request) {
try {
const trends = await fetchFromMultipleSources();
const countryCode = geolocation(req).countryRegion ?? 'US';
const trends = await fetchFromMultipleSources(countryCode);
if (trends.length === 0) {
// Fallback queries if both sources fail
console.error('Both sources failed to fetch trends, returning fallback queries');
return NextResponse.json([
{
icon: 'sparkles',

View File

@ -1,7 +1,16 @@
@import url('https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=Instrument+Serif:wght@400&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--font-serif: "Instrument Serif", serif;
}
body {
font-family: var(--font-sans), sans-serif;
}
.homeBtn {
box-shadow: rgba(0, 0, 0, 0.4) 0px 2px 4px,
rgba(0, 0, 0, 0.3) 0px 7px 13px -3px, rgba(0, 0, 0, 0.2) 0px -3px 0px inset,

View File

@ -1,13 +1,12 @@
import { Analytics } from "@vercel/analytics/react";
import { GeistSans } from 'geist/font/sans';
import "./globals.css";
import 'katex/dist/katex.min.css';
import 'mapbox-gl/dist/mapbox-gl.css';
import { Metadata, Viewport } from "next";
import { Instrument_Serif } from 'next/font/google';
import { NuqsAdapter } from 'nuqs/adapters/next/app';
import { Toaster } from "sonner";
import "./globals.css";
import { Providers } from './providers';
import { Instrument_Serif } from 'next/font/google';
import { Analytics } from "@vercel/analytics/react";
import { Providers } from './providers'
import { GeistSans } from 'geist/font/sans';
export const metadata: Metadata = {
metadataBase: new URL("https://mplx.run"),
@ -44,11 +43,7 @@ export const viewport: Viewport = {
const instrumentSerif = Instrument_Serif({
weight: "400",
subsets: ["latin"],
style: ['normal', 'italic'],
variable: "--font-serif",
preload: true,
display: 'swap',
fallback: ['sans-serif'],
variable: "--font-serif"
})
export default function RootLayout({
@ -58,13 +53,11 @@ export default function RootLayout({
}>) {
return (
<html lang="en">
<body className={`${GeistSans.variable} ${instrumentSerif.variable} font-sans antialiased`}>
<NuqsAdapter>
<Providers>
<Toaster position="top-center" richColors />
{children}
</Providers>
</NuqsAdapter>
<body className={` ${GeistSans.className} ${instrumentSerif.className}`}>
<Providers>
<Toaster position="top-center" richColors />
{children}
</Providers>
<Analytics />
</body>
</html>

View File

@ -2,133 +2,137 @@
"use client";
import 'katex/dist/katex.min.css';
import { BorderTrail } from '@/components/core/border-trail';
import { TextShimmer } from '@/components/core/text-shimmer';
import { FlightTracker } from '@/components/flight-tracker';
import { InstallPrompt } from '@/components/InstallPrompt';
import
React,
{
useRef,
useCallback,
useState,
useEffect,
useMemo,
Suspense
} from 'react';
import ReactMarkdown from 'react-markdown';
import { useTheme } from 'next-themes';
import Marked, { ReactRenderer } from 'marked-react';
import Latex from 'react-latex-next';
import { useSearchParams } from 'next/navigation';
import { useChat } from 'ai/react';
import { ToolInvocation } from 'ai';
import { toast } from 'sonner';
import { motion, AnimatePresence } from 'framer-motion';
import Image from 'next/image';
import {
fetchMetadata,
generateSpeech,
suggestQuestions
} from './actions';
import { Wave } from "@foobar404/wave";
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { oneLight, oneDark } from 'react-syntax-highlighter/dist/esm/styles/prism';
import {
Sparkles,
ArrowRight,
Globe,
AlignLeft,
Copy,
Cloud,
Code,
Check,
Loader2,
User2,
Heart,
X,
MapPin,
Plus,
Download,
Flame,
Sun,
Pause,
Play,
TrendingUpIcon,
Calendar,
Calculator,
ChevronDown,
Edit2,
ChevronUp,
Moon,
Star,
YoutubeIcon,
LucideIcon,
FileText,
Book,
ExternalLink,
Building,
Users,
Brain,
TrendingUp,
Plane,
Film,
Tv,
ListTodo
} from 'lucide-react';
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip"
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';
import { Badge } from '@/components/ui/badge';
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger } from "@/components/ui/drawer";
import { GitHubLogoIcon, TextIcon } from '@radix-ui/react-icons';
import Link from 'next/link';
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Carousel, CarouselContent, CarouselItem } from "@/components/ui/carousel";
import { cn, SearchGroupId } from '@/lib/utils';
import {
Table,
TableBody,
TableCell,
TableRow,
} from "@/components/ui/table";
import Autoplay from 'embla-carousel-autoplay';
import FormComponent from '@/components/ui/form-component';
import WeatherChart from '@/components/weather-chart';
import InteractiveChart from '@/components/interactive-charts';
import { MapComponent, MapContainer } from '@/components/map-components';
import TMDBResult from '@/components/movie-info';
import MultiSearch from '@/components/multi-search';
import NearbySearchMapView from '@/components/nearby-search-map-view';
import TrendingResults from '@/components/trending-tv-movies-results';
import {
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
import { Badge } from '@/components/ui/badge';
import { Button } from '@/components/ui/button';
import {
Card,
CardContent,
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Carousel, CarouselContent, CarouselItem } from "@/components/ui/carousel";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Drawer, DrawerContent, DrawerHeader, DrawerTitle, DrawerTrigger } from "@/components/ui/drawer";
import FormComponent from '@/components/ui/form-component';
import {
HoverCard,
HoverCardContent,
HoverCardTrigger,
} from "@/components/ui/hover-card";
import { Input } from '@/components/ui/input';
import { Separator } from '@/components/ui/separator';
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetTrigger } from "@/components/ui/sheet";
import {
Table,
TableBody,
TableCell,
TableRow,
} from "@/components/ui/table";
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip";
import WeatherChart from '@/components/weather-chart';
import { useMediaQuery } from '@/hooks/use-media-query';
import { cn, SearchGroupId } from '@/lib/utils';
import { Wave } from "@foobar404/wave";
import { CurrencyDollar, Flag, RoadHorizon, SoccerBall, TennisBall, XLogo } from '@phosphor-icons/react';
import { GitHubLogoIcon, TextIcon } from '@radix-ui/react-icons';
import { ToolInvocation } from 'ai';
import { useChat } from 'ai/react';
import Autoplay from 'embla-carousel-autoplay';
import { AnimatePresence, motion } from 'framer-motion';
import { GeistMono } from 'geist/font/mono';
import {
AlignLeft,
ArrowRight,
Book,
Brain,
Building,
Calculator,
Calendar,
Check,
ChevronDown,
ChevronUp,
Cloud,
Code,
Copy,
Download,
Edit2,
ExternalLink,
FileText,
Film,
Flame,
Globe,
Heart,
ListTodo,
Loader2,
LucideIcon,
MapPin,
Moon,
Pause,
Plane,
Play,
Plus,
Sparkles,
Sun,
TrendingUp,
TrendingUpIcon,
Tv,
User2,
Users,
X,
YoutubeIcon
} from 'lucide-react';
import Marked, { ReactRenderer } from 'marked-react';
import { useTheme } from 'next-themes';
import Image from 'next/image';
import Link from 'next/link';
import { parseAsString, useQueryState } from 'nuqs';
import React, {
Suspense,
useCallback,
useEffect,
useMemo,
useRef,
useState
} from 'react';
import Latex from 'react-latex-next';
import ReactMarkdown from 'react-markdown';
import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter';
import { atomDark, vs } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import { oneDark, oneLight } from 'react-syntax-highlighter/dist/esm/styles/prism';
import { BorderTrail } from '@/components/core/border-trail';
import { TextShimmer } from '@/components/core/text-shimmer';
import { Tweet } from 'react-tweet';
import { toast } from 'sonner';
import {
fetchMetadata,
generateSpeech,
suggestQuestions
} from './actions';
import NearbySearchMapView from '@/components/nearby-search-map-view';
import { Separator } from '@/components/ui/separator';
import { TrendingQuery } from './api/trending/route';
import { FlightTracker } from '@/components/flight-tracker';
import { InstallPrompt } from '@/components/InstallPrompt';
import { atomDark } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import { vs } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import { useMediaQuery } from '@/hooks/use-media-query';
import TMDBResult from '@/components/movie-info';
import TrendingResults from '@/components/trending-tv-movies-results';
import { GeistMono } from 'geist/font/mono';
export const maxDuration = 60;
@ -559,15 +563,12 @@ const SponsorDialog = ({
};
const HomeContent = () => {
const [query] = useQueryState('query', parseAsString.withDefault(''))
const [q] = useQueryState('q', parseAsString.withDefault(''))
const [model] = useQueryState('model', parseAsString.withDefault('grok-2-1212'))
const searchParams = useSearchParams();
// Memoize initial values to prevent re-calculation
const initialState = useMemo(() => ({
query: query || q,
model: model
// eslint-disable-next-line react-hooks/exhaustive-deps
query: searchParams.get('query') || searchParams.get('q') || '',
model: searchParams.get('model') || 'grok-2-1212'
}), []); // Empty dependency array as we only want this on mount
const lastSubmittedQueryRef = useRef(initialState.query);
@ -698,7 +699,6 @@ const HomeContent = () => {
};
fetchTrending();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, []);
const ThemeToggle: React.FC = () => {
@ -758,12 +758,12 @@ const HomeContent = () => {
id: "1",
title: "The Unexpected Collab",
images: [
"https://metwm7frkvew6tn1.public.blob.vercel-storage.com/mplx-changelogs/mplx-collab.jpeg",
"https://metwm7frkvew6tn1.public.blob.vercel-storage.com/mplx-changelogs/mplx-collab.jpeg",
],
content: `
## **MiniPerplx x Vercel x xAI Collab**
Excited to annouce that MiniPerplx has partnered with Vercel and xAI to bring you the best of AI search experience.
Excited to annouce that MiniPerplx has partnered with Vercel and xAI to bring you the best of AI search experience.
Grok 2 models are now available for you to try out.
`
}
@ -892,11 +892,10 @@ Grok 2 models are now available for you to try out.
const waveRef = useRef<Wave | null>(null);
useEffect(() => {
const _audioRef = audioRef.current
return () => {
if (_audioRef) {
_audioRef.pause();
_audioRef.src = '';
if (audioRef.current) {
audioRef.current.pause();
audioRef.current.src = '';
}
};
}, []);
@ -1290,7 +1289,7 @@ Grok 2 models are now available for you to try out.
return <TrendingResults result={result} type="tv" />;
}
if (toolInvocation.toolName === 'x_search') {
if (!result) {
return <SearchLoadingState
@ -2118,10 +2117,10 @@ Grok 2 models are now available for you to try out.
<button
onClick={handleCopy}
className={`
px-2 py-1.5
px-2 py-1.5
rounded-md text-xs
transition-colors duration-200
${isCopied ? 'bg-green-500/10 text-green-500' : 'bg-neutral-100 dark:bg-neutral-800 text-neutral-500 dark:text-neutral-400'}
${isCopied ? 'bg-green-500/10 text-green-500' : 'bg-neutral-100 dark:bg-neutral-800 text-neutral-500 dark:text-neutral-400'}
opacity-0 group-hover:opacity-100
hover:bg-neutral-200 dark:hover:bg-neutral-700
flex items-center gap-1.5
@ -2542,8 +2541,8 @@ Grok 2 models are now available for you to try out.
<button
key={`${index}-${query.text}`}
onClick={() => handleExampleClick(query)}
className="group flex-shrink-0 bg-neutral-50/50 dark:bg-neutral-800/50
backdrop-blur-sm rounded-xl p-3.5 text-left
className="group flex-shrink-0 bg-neutral-50/50 dark:bg-neutral-800/50
backdrop-blur-sm rounded-xl p-3.5 text-left
hover:bg-neutral-100 dark:hover:bg-neutral-700/70
transition-all duration-200 ease-out
hover:scale-102 origin-center
@ -2589,7 +2588,6 @@ Grok 2 models are now available for you to try out.
<SuggestionCards
trendingQueries={trendingQueries}
/>
// eslint-disable-next-line react-hooks/exhaustive-deps
), [trendingQueries]);
return (

View File

@ -1,60 +0,0 @@
version: '3.8'
services:
web:
build:
context: .
dockerfile: Dockerfile
ports:
- "3000:3000"
environment:
- NODE_ENV=production
- XAI_API_KEY=${XAI_API_KEY}
- UPSTASH_REDIS_REST_URL=${UPSTASH_REDIS_REST_URL}
- UPSTASH_REDIS_REST_TOKEN=${UPSTASH_REDIS_REST_TOKEN}
- ELEVENLABS_API_KEY=${ELEVENLABS_API_KEY}
- TAVILY_API_KEY=${TAVILY_API_KEY}
- EXA_API_KEY=${EXA_API_KEY}
- TMDB_API_KEY=${TMDB_API_KEY}
- YT_ENDPOINT=${YT_ENDPOINT}
- FIRECRAWL_API_KEY=${FIRECRAWL_API_KEY}
- OPENWEATHER_API_KEY=${OPENWEATHER_API_KEY}
- SANDBOX_TEMPLATE_ID=${SANDBOX_TEMPLATE_ID}
- GOOGLE_MAPS_API_KEY=${GOOGLE_MAPS_API_KEY}
- MAPBOX_ACCESS_TOKEN=${MAPBOX_ACCESS_TOKEN}
- AZURE_TRANSLATOR_KEY=${AZURE_TRANSLATOR_KEY}
- AZURE_TRANSLATOR_LOCATION=${AZURE_TRANSLATOR_LOCATION}
- AZURE_RESOURCE_NAME=${AZURE_RESOURCE_NAME}
- AZURE_API_KEY=${AZURE_API_KEY}
- TRIPADVISOR_API_KEY=${TRIPADVISOR_API_KEY}
- AVIATION_STACK_API_KEY=${AVIATION_STACK_API_KEY}
- CRON_SECRET=${CRON_SECRET}
- BLOB_READ_WRITE_TOKEN=${BLOB_READ_WRITE_TOKEN}
- NEXT_PUBLIC_MAPBOX_TOKEN=${NEXT_PUBLIC_MAPBOX_TOKEN}
- NEXT_PUBLIC_POSTHOG_KEY=${NEXT_PUBLIC_POSTHOG_KEY}
- NEXT_PUBLIC_POSTHOG_HOST=${NEXT_PUBLIC_POSTHOG_HOST}
- NEXT_PUBLIC_GOOGLE_MAPS_API_KEY=${NEXT_PUBLIC_GOOGLE_MAPS_API_KEY}
volumes:
- .:/app
- /app/node_modules
depends_on:
- code-interpreter
code-interpreter:
build:
context: .
dockerfile: e2b.Dockerfile
environment:
- E2B_API_KEY=${E2B_API_KEY}
volumes:
- ./certificates:/app/certificates
redis:
image: redis:alpine
ports:
- "6379:6379"
volumes:
- redis_data:/data
volumes:
redis_data:

3
env/client.ts vendored
View File

@ -7,13 +7,10 @@ export const clientEnv = createEnv({
NEXT_PUBLIC_MAPBOX_TOKEN: z.string().min(1),
NEXT_PUBLIC_POSTHOG_KEY: z.string().min(1),
NEXT_PUBLIC_POSTHOG_HOST: z.string().min(1).url(),
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY: z.string().min(1),
},
runtimeEnv: {
NEXT_PUBLIC_MAPBOX_TOKEN: process.env.NEXT_PUBLIC_MAPBOX_TOKEN,
NEXT_PUBLIC_POSTHOG_KEY: process.env.NEXT_PUBLIC_POSTHOG_KEY,
NEXT_PUBLIC_POSTHOG_HOST: process.env.NEXT_PUBLIC_POSTHOG_HOST,
NEXT_PUBLIC_GOOGLE_MAPS_API_KEY: process.env.NEXT_PUBLIC_GOOGLE_MAPS_API_KEY
},
})

6
env/server.ts vendored
View File

@ -4,9 +4,6 @@ import { z } from 'zod'
export const serverEnv = createEnv({
server: {
XAI_API_KEY: z.string().min(1),
UPSTASH_REDIS_REST_URL: z.string().min(1).url(),
UPSTASH_REDIS_REST_TOKEN: z.string().min(1),
ELEVENLABS_API_KEY: z.string().min(1),
TAVILY_API_KEY: z.string().min(1),
EXA_API_KEY: z.string().min(1),
@ -19,12 +16,9 @@ export const serverEnv = createEnv({
MAPBOX_ACCESS_TOKEN: z.string().min(1),
AZURE_TRANSLATOR_KEY: z.string().min(1),
AZURE_TRANSLATOR_LOCATION: z.string().min(1),
AZURE_RESOURCE_NAME: z.string().min(1),
AZURE_API_KEY: z.string().min(1),
TRIPADVISOR_API_KEY: z.string().min(1),
AVIATION_STACK_API_KEY: z.string().min(1),
CRON_SECRET: z.string().min(1),
BLOB_READ_WRITE_TOKEN: z.string().min(1),
},
experimental__runtimeEnv: process.env,
})

View File

@ -9,86 +9,86 @@ jiti.import('./env/client')
/** @type {import('next').NextConfig} */
const nextConfig = {
transpilePackages: ["geist"],
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
],
},
]
},
images: {
dangerouslyAllowSVG: true,
remotePatterns: [
{
protocol: 'https',
hostname: 'www.google.com',
port: '',
pathname: '/s2/favicons',
},
{
protocol: 'https',
hostname: 'api.producthunt.com',
port: '',
pathname: '/widgets/embed-image/v1/featured.svg',
},
{
protocol: 'https',
hostname: 'metwm7frkvew6tn1.public.blob.vercel-storage.com',
port: '',
pathname: "**"
},
// upload.wikimedia.org
{
protocol: 'https',
hostname: 'upload.wikimedia.org',
port: '',
pathname: '**'
},
// media.theresanaiforthat.com
{
protocol: 'https',
hostname: 'media.theresanaiforthat.com',
port: '',
pathname: '**'
},
// www.uneed.best
{
protocol: 'https',
hostname: 'www.uneed.best',
port: '',
pathname: '**'
},
// image.tmdb.org
{
protocol: 'https',
hostname: 'image.tmdb.org',
port: '',
pathname: '/t/p/original/**'
},
// image.tmdb.org
{
protocol: 'https',
hostname: 'image.tmdb.org',
port: '',
pathname: '/**'
},
]
},
};
transpilePackages: ['geist'],
async headers() {
return [
{
source: '/(.*)',
headers: [
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'X-Frame-Options',
value: 'DENY',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
],
},
]
},
images: {
dangerouslyAllowSVG: true,
remotePatterns: [
{
protocol: 'https',
hostname: 'www.google.com',
port: '',
pathname: '/s2/favicons',
},
{
protocol: 'https',
hostname: 'api.producthunt.com',
port: '',
pathname: '/widgets/embed-image/v1/featured.svg',
},
{
protocol: 'https',
hostname: 'metwm7frkvew6tn1.public.blob.vercel-storage.com',
port: '',
pathname: '**',
},
// upload.wikimedia.org
{
protocol: 'https',
hostname: 'upload.wikimedia.org',
port: '',
pathname: '**',
},
// media.theresanaiforthat.com
{
protocol: 'https',
hostname: 'media.theresanaiforthat.com',
port: '',
pathname: '**',
},
// www.uneed.best
{
protocol: 'https',
hostname: 'www.uneed.best',
port: '',
pathname: '**',
},
// image.tmdb.org
{
protocol: 'https',
hostname: 'image.tmdb.org',
port: '',
pathname: '/t/p/original/**',
},
// image.tmdb.org
{
protocol: 'https',
hostname: 'image.tmdb.org',
port: '',
pathname: '/**',
},
],
},
}
export default nextConfig;
export default nextConfig

View File

@ -64,7 +64,6 @@
"motion": "^11.13.5",
"next": "^14.2.21",
"next-themes": "^0.3.0",
"nuqs": "^2.3.0",
"openai": "^4.56.0",
"posthog-js": "^1.202.2",
"react": "^18",

View File

@ -173,9 +173,6 @@ importers:
next-themes:
specifier: ^0.3.0
version: 0.3.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
nuqs:
specifier: ^2.3.0
version: 2.3.0(next@14.2.21(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1)
openai:
specifier: ^4.56.0
version: 4.67.2(zod@3.24.1)
@ -2789,9 +2786,6 @@ packages:
resolution: {integrity: sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==}
engines: {node: '>=16 || 14 >=14.17'}
mitt@3.0.1:
resolution: {integrity: sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw==}
motion-dom@11.13.0:
resolution: {integrity: sha512-Oc1MLGJQ6nrvXccXA89lXtOqFyBmvHtaDcTRGT66o8Czl7nuA8BeHAd9MQV1pQKX0d2RHFBFaw5g3k23hQJt0w==}
@ -2883,24 +2877,6 @@ packages:
nth-check@2.1.1:
resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
nuqs@2.3.0:
resolution: {integrity: sha512-ChS56bJZdaTQzCJb6jPel6cIHYh8/V/GSIjZoIe5yAssGdcrVaBFBgzHfJW6IewbR6yc1Zch2CmGsdgztR+xmA==}
peerDependencies:
'@remix-run/react': '>=2'
next: '>=14.2.0'
react: '>=18.2.0 || ^19.0.0-0'
react-router: ^7
react-router-dom: ^6 || ^7
peerDependenciesMeta:
'@remix-run/react':
optional: true
next:
optional: true
react-router:
optional: true
react-router-dom:
optional: true
object-assign@4.1.1:
resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==}
engines: {node: '>=0.10.0'}
@ -6759,8 +6735,6 @@ snapshots:
minipass@7.1.2: {}
mitt@3.0.1: {}
motion-dom@11.13.0: {}
motion-utils@11.13.0: {}
@ -6834,13 +6808,6 @@ snapshots:
dependencies:
boolbase: 1.0.0
nuqs@2.3.0(next@14.2.21(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1))(react@18.3.1):
dependencies:
mitt: 3.0.1
react: 18.3.1
optionalDependencies:
next: 14.2.21(@opentelemetry/api@1.9.0)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
object-assign@4.1.1: {}
object-hash@3.0.0: {}

View File

@ -1,5 +1,4 @@
import type { Config } from "tailwindcss";
import { fontFamily } from 'tailwindcss/defaultTheme';
const config = {
darkMode: ["class"],
@ -24,9 +23,9 @@ const config = {
'screen-small': '100svh',
},
fontFamily: {
sans: ['var(--font-geist-sans)', ...fontFamily.sans],
serif: ['var(--font-serif)', ...fontFamily.serif],
mono: ['var(--font-geist-mono)', ...fontFamily.mono],
sans: ['var(--font-geist-sans)'],
serif: ['var(--font-serif)'],
mono: ['var(--font-geist-mono)'],
},
colors: {
border: "hsl(var(--border))",
@ -88,11 +87,7 @@ const config = {
},
},
},
plugins: [
require("tailwindcss-animate"),
require("@tailwindcss/typography"),
require("tailwind-scrollbar")
],
plugins: [require("tailwindcss-animate"), require("@tailwindcss/typography"),require("tailwind-scrollbar")],
} satisfies Config
export default config