Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Please help me, I want to build my project, but this is the error that comes out: node_modules\quill\dist\quill.js (7661:11) @ document ⨯ ReferenceError: document is not defined #968

Open
KhasanshinRamis opened this issue Apr 9, 2024 · 1 comment

Comments

@KhasanshinRamis
Copy link

Please help me, I want to build my project, but this is the error that comes out:

node_modules\quill\dist\quill.js (7661:11) @ document
 ⨯ ReferenceError: document is not defined
    at __webpack_require__ (C:\Users\Ramis\Desktop\React+Next.js\vip-app\.next\server\webpack-runtime.js:33:43)
    at __webpack_require__ (C:\Users\Ramis\Desktop\React+Next.js\vip-app\.next\server\webpack-runtime.js:33:43)
    at eval (./src/components/ui/textEditor.tsx:9:69)
    at (ssr)/./src/components/ui/textEditor.tsx (C:\Users\Ramis\Desktop\React+Next.js\vip-app\.next\server\app\(protected)\write\page.js:778:1)      
    at __webpack_require__ (C:\Users\Ramis\Desktop\React+Next.js\vip-app\.next\server\webpack-runtime.js:33:43)
    at eval (write/page.tsx:25:84)
    at (ssr)/./src/app/(protected)/write/page.tsx (C:\Users\Ramis\Desktop\React+Next.js\vip-app\.next\server\app\(protected)\write\page.js:536:1)    
    at __webpack_require__ (C:\Users\Ramis\Desktop\React+Next.js\vip-app\.next\server\webpack-runtime.js:33:43)
    at JSON.parse (<anonymous>)

My Components:

'use client';

import { Button } from '@/components/ui/button';
import ReactQuill from 'react-quill';
import 'react-quill/dist/quill.bubble.css';
import { Input } from '@/components/ui/input';
import { Form, FormControl, FormItem, FormLabel, FormMessage, FormField } from '@/components/ui/form';
import { FormError } from '@/components/formError';
import { FormSuccess } from '@/components/formSuccess';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { useForm } from 'react-hook-form';
import { FaFileImage } from "react-icons/fa";
import { zodResolver } from '@hookform/resolvers/zod';
import { NewPostSchema } from '@/schemas';
import {
	getStorage,
	ref,
	uploadBytesResumable,
	getDownloadURL,
} from "firebase/storage";
import * as z from 'zod';
import { useEffect, useState } from 'react';
import postService from '@/services/postService';
import { app } from '@/config/firebase';



export default function WritePage() {
	const queryClient = useQueryClient();



	const [media, setMedia] = useState<string>('');
	const [file, setFile] = useState<Blob | Uint8Array | ArrayBuffer>();
	const [disabledFromMedia, setDisabledFromMedia] = useState<boolean>(false);

	const [success, setSuccess] = useState<string | undefined>('');
	const [errorMessage, setErrorMessage] = useState<string | undefined>('');

	useEffect(() => {
		const storage = getStorage(app);
		const upload = () => {
			if (file) {

				const name = new Date().getTime().toString();
				const storageRef = ref(storage, name);

				const uploadTask = uploadBytesResumable(storageRef, file);

				uploadTask.on(
					"state_changed",
					(snapshot) => {
						const progress =
							(snapshot.bytesTransferred / snapshot.totalBytes) * 100;
						console.log("Upload is " + progress + "% done");
						switch (snapshot.state) {
							case "paused":
								console.log("Upload is paused");
								break;
							case "running":
								console.log("Upload is running");
								break;
						}
					},
					(error) => { console.log(error.message) },
					() => {
						getDownloadURL(uploadTask.snapshot.ref).then((downloadURL) => {
							setMedia(downloadURL);
							setDisabledFromMedia(true);
							console.log('File available at', downloadURL);
						});
					}
				);
			}
		};

		file && upload();
	}, [file]);

	const form = useForm<z.infer<typeof NewPostSchema>>({
		resolver: zodResolver(NewPostSchema)
	});

	const mutation = useMutation({
		mutationKey: ['new-post'],
		mutationFn: (values: z.infer<typeof NewPostSchema>) => postService.create(values),
		onSuccess: (data: any) => {
			console.log('Success!', data);
			console.log(data.success);
			setSuccess('Новая запись создана!');
			queryClient.invalidateQueries({ queryKey: ['new-post'] });
		},
		onError: (error: any) => {
			console.log(error.message);
			setErrorMessage(error.response.data.error);
			queryClient.invalidateQueries({ queryKey: ['new-post'] });
		}
	});

	const slugify = (str: string) => str.toLowerCase().trim().replace(/\W_/g, "").replace(/\s/g, "-").replace(/^-+|-+$/g, "").replace(/а/g, "a").replace(/б/g, "b").replace(/в/g, "v").replace(/г/g, "g").replace(/д/g, "d").replace(/е/g, "e").replace(/ё/g, "yo").replace(/ж/g, "zh").replace(/з/g, "z").replace(/и/g, "i").replace(/й/g, "y").replace(/к/g, "k").replace(/л/g, "l").replace(/м/g, "m").replace(/н/g, "n").replace(/о/g, "o").replace(/п/g, "p").replace(/р/g, "r").replace(/с/g, "s").replace(/т/g, "t").replace(/у/g, "u").replace(/ф/g, "f").replace(/х/g, "kh").replace(/ц/g, "ts").replace(/ч/g, "ch").replace(/ш/g, "sh").replace(/щ/g, "shch").replace(/ъ/g, "").replace(/ы/g, "y").replace(/ь/g, "").replace(/э/g, "e").replace(/ю/g, "yu").replace(/я/g, "ya").slice(0, 30);


	const onSubmit = (values: z.infer<typeof NewPostSchema>) => {
		console.log(media);
		const updatedValues = {
			img: media,
			slug: slugify(values.title),
			...values
		};
		console.log('image mutation', updatedValues.image);
		mutation.mutate(
			updatedValues
		);
	};


	console.log("media: ", media);
	console.log("file: ", file);

	return (
		<div className='min-h-screen'>
			<Form {...form}>
				<form
					className='grid grid-rows-[64px_36px_32px_1fr_36px] gap-y-8 px-24 sm:px-4 py-6 h-full'
					onSubmit={form.handleSubmit(onSubmit)}
				>
					<FormField
						control={form.control}
						name='title'
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<Input
										{...field}
										placeholder='Заголовок'
										className='text-3xl md:text-xl pl-0 py-8 text-white placeholder:text-white focus:border-none focus:outline-none border-none bg-transparent outline-none shadow-none'
										disabled={mutation.isPending}
									/>
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						name='category'
						render={({ field }) => (
							<FormItem>
								<Select
									disabled={mutation.isPending}
									onValueChange={field.onChange}
								>
									<FormControl>
										<SelectTrigger>
											<SelectValue
												placeholder='Выберите категорию'

											/>
										</SelectTrigger>
									</FormControl>
									<SelectContent>
										<SelectItem value='style'>
											Стиль
										</SelectItem>
										<SelectItem value='fashion'>
											Мода
										</SelectItem>
										<SelectItem value='food'>
											Еда
										</SelectItem>
										<SelectItem value='culture'>
											Культура
										</SelectItem>
										<SelectItem value='travel'>
											Путешествие
										</SelectItem>
										<SelectItem value='coding'>
											Программирование
										</SelectItem>
									</SelectContent>
								</Select>
								<FormMessage />
							</FormItem>
						)}
					/>
					<FormField
						control={form.control}
						name='image'
						render={({ field }) => (
							<FormItem>
								<FormLabel
									className='grid justify-center items-center bg-indigo-900 w-[32px] h-[32px] rounded-[50%]'
									htmlFor="image"
								>
									<FaFileImage width={16} height={16} color='#F5EFEF' />
								</FormLabel>
								<FormControl>
									<Input
										{...field}
										type="file"
										id='image'
										disabled={mutation.isPending}
										onChange={(event) => {
											if (event.target.files && event.target.files.length > 0) {
												setFile(event.target.files[0]);
											}
										}}
										style={{ display: 'none' }}
									/>
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>

					<FormField
						control={form.control}
						name='description'
						render={({ field }) => (
							<FormItem>
								<FormControl>
									<ReactQuill
										{...field}
										theme='bubble'
										placeholder='Расскажи свою историю...'
										className='[&>div>div>p]:text-base [&>div>div>p]:text-white [&>div>div>p]:placeholder:text-white placeholder:[&>div>div>p]:text-2xl md:placeholder:[&>div>div>p]:text-lg [&>div>div>h1]:text-white  [&>div>div>h1]:text-text-3xl md:placeholder:[&>div>div>h1]:text-xl [&>div>div>h2]:text-white [&>div>div>h2]:text-xl [&>div>div>ol>li]:text-base [&>div>div>ol>li]:text-white'
									/>
								</FormControl>
								<FormMessage />
							</FormItem>
						)}
					/>


					<FormError message={errorMessage} />
					<FormSuccess message={success} />
					<Button
						type='submit'
						className='grid items-end'
						disabled={mutation.isPending && disabledFromMedia}
					>
						Создать новую запись
					</Button>
				</form>
			</Form>
		</div>
	);

}
@JardelCheung
Copy link

U can use dynamic in next/dynamic to resolve this issue.

exa:

import dynamic from "next/dynamic";
const ReactQuill = dynamic(
    () => {
        return import("react-quill");
    },
    {ssr: false}
);

return(
<ReactQuill/>
)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants