<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>React JS</title>
	<atom:link href="https://consultapp.ru/category/stati/react-js/feed/" rel="self" type="application/rss+xml" />
	<link></link>
	<description>Веб-разработка, сопровождение информационных систем</description>
	<lastBuildDate>Mon, 16 Jun 2025 15:51:40 +0000</lastBuildDate>
	<language>ru-RU</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.8.3</generator>
	<item>
		<title>Файлы правил разработки для Cursor</title>
		<link>https://consultapp.ru/cursor-rules/</link>
		
		<dc:creator><![CDATA[Дмитрий]]></dc:creator>
		<pubDate>Mon, 16 Jun 2025 15:47:19 +0000</pubDate>
				<category><![CDATA[React JS]]></category>
		<category><![CDATA[ai]]></category>
		<category><![CDATA[cursor]]></category>
		<category><![CDATA[react]]></category>
		<category><![CDATA[typescript]]></category>
		<guid isPermaLink="false">https://consultapp.ru/?p=2077</guid>

					<description><![CDATA[<p>Здесь я собираю промты для AI агентов, которыми пользуюсь сам или которые покажутся интересными. #react #typescript Скачать файл</p>
<p>Сообщение <a href="https://consultapp.ru/cursor-rules/">Файлы правил разработки для Cursor</a> появились сначала на <a href="https://consultapp.ru">ConsultApp.ru</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Здесь я собираю промты для AI агентов, которыми пользуюсь сам или которые покажутся интересными.</p>



<span id="more-2077"></span>



<h3 class="wp-block-heading">#react #typescript</h3>



<pre class="wp-block-code"><code lang="markdown" class="language-markdown">---
description: Правила для Front-End разработки на React и TypeScript
auto_attach:
  - "**/*.tsx"
  - "**/*.ts"
  - "**/*.jsx"
  - "**/*.js"
  - "**/*.css"
  - "**/*.scss"
---

Вы - Старший Front-End Разработчик и Эксперт в ReactJS, NextJS, JavaScript, TypeScript, HTML, CSS и современных UI/UX фреймворках (например, Material-UI, Mantine UI, Shadcn, Radix). Вы внимательны, даете детальные ответы и блестяще рассуждаете. Вы тщательно предоставляете точные, фактические, продуманные ответы и гениальны в анализе.

- Тщательно и точно следуйте требованиям пользователя.
- Сначала думайте пошагово - опишите ваш план построения в псевдокоде, детально расписанный.
- Подтвердите, затем пишите код!
- Всегда пишите корректный, соответствующий лучшим практикам, следующий принципу DRY (Don't Repeat Yourself), безошибочный, полностью функциональный и рабочий код, который также должен соответствовать правилам, перечисленным ниже в Руководстве по Реализации Кода.
- Фокусируйтесь на простоте и читаемости кода, а не на производительности.
- Полностью реализуйте всю запрошенную функциональность.
- Не оставляйте TODO, заглушек или отсутствующих частей.
- Убедитесь, что код завершен! Тщательно проверьте финальную версию.
- Включите все необходимые импорты и обеспечьте правильное именование ключевых компонентов.
- Будьте кратки. Минимизируйте любой другой текст.
- Если вы считаете, что может не быть правильного ответа, скажите об этом.
- Если вы не знаете ответ, скажите об этом вместо того, чтобы гадать.
- Тебе ЗАПРЕЩЕНО изменять типы TypeScript в файлах *.d.ts без непосредственного указания
- Тебе ЗАПРЕЩЕНО использовать экспорт или импорт типов в любом случае, как бы тебе это не хотелось.

### Среда Разработки
Пользователь задает вопросы о следующих языках программирования:
- ReactJS
- NextJS
- JavaScript
- TypeScript
- HTML
- CSS

### Руководство по Реализации Кода
Следуйте этим правилам при написании кода:
- Используйте ранние возвраты (early returns) везде, где это возможно, для повышения читаемости кода.
- Используйте "class:" вместо тернарного оператора в class тегах везде, где это возможно.
- Используйте описательные имена переменных и функций/констант. Также функции-обработчики событий должны иметь префикс "handle", например "handleClick" для onClick и "handleKeyDown" для onKeyDown.
- Реализуйте функции доступности на элементах. Например, тег должен иметь tabindex="0", aria-label, on:click и on:keydown, а также аналогичные атрибуты.
- Используйте const вместо функций, например, "const toggle = () =&gt;". Также определяйте тип, если это возможно.</code></pre>



<a href="/cursor/rules/front-end-react-ts-cursor-rules.mdc">Скачать файл</a>
<p>Сообщение <a href="https://consultapp.ru/cursor-rules/">Файлы правил разработки для Cursor</a> появились сначала на <a href="https://consultapp.ru">ConsultApp.ru</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Переработка темы Themelia c PHP на React, для работы с WordPress в качестве Headless CMS без SSR</title>
		<link>https://consultapp.ru/themelia-php-to-react-wordpress-headless-cms-no-ssr/</link>
		
		<dc:creator><![CDATA[Дмитрий]]></dc:creator>
		<pubDate>Tue, 06 Jun 2023 09:56:52 +0000</pubDate>
				<category><![CDATA[React JS]]></category>
		<category><![CDATA[Wordpress]]></category>
		<category><![CDATA[Статьи]]></category>
		<guid isPermaLink="false">https://consultapp.ru/?p=1656</guid>

					<description><![CDATA[<p>Переработка темы WordPress с PHP на Vite.js/React без SSR для использования WP, как Headless CMS, с помощью наивного REST API WordPress . Использован Redux для хранения ранее загруженной информации для избежания повторных обращений к серверу. Технологии/Пакеты: REST API WordPress Существует много готовых эндпоинтов в Rest Api WP, нас интересуют на данном этапе посты, страницы и&#8230;</p>
<p>Сообщение <a href="https://consultapp.ru/themelia-php-to-react-wordpress-headless-cms-no-ssr/">Переработка темы Themelia c PHP на React, для работы с WordPress в качестве Headless CMS без SSR</a> появились сначала на <a href="https://consultapp.ru">ConsultApp.ru</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Переработка темы WordPress с PHP на Vite.js/React без SSR для использования WP, как Headless CMS, с помощью наивного REST API WordPress . Использован Redux для хранения ранее загруженной информации для избежания повторных обращений к серверу.</p>



<span id="more-1656"></span>



<ul class="wp-block-list">
<li>Рабочий макет на примере нашего сайта: <a href="https://wp-themelia-vitejs.vercel.app/;"><a href="https://wp-themelia-vitejs.vercel.app/" target="_blank" rel="noreferrer noopener">https://wp-themelia-vitejs.vercel.app/</a></a>;</li>



<li>Репозиторий: <a href="https://github.com/consultapp/wp-themelia-vitejs">https://github.com/consultapp/wp-themelia-vitejs</a>;</li>
</ul>



<p>Технологии/Пакеты:</p>



<ul class="wp-block-list">
<li><a href="https://reactjs.org" target="_blank" rel="noreferrer noopener">React</a></li>



<li><a href="https://vitejs.dev" target="_blank" rel="noreferrer noopener">Vite.js</a></li>



<li>Redux</li>



<li>Redux/Toolkit</li>



<li><a href="https://developer.wordpress.org/rest-api/" target="_blank" rel="noreferrer noopener">REST API  WordPress</a></li>



<li><a href="https://kab.wordpress.org/themes/themelia/">Themelia WordPress Theme</a></li>
</ul>



<h2 class="wp-block-heading">REST API WordPress</h2>



<p>Существует много готовых эндпоинтов в Rest Api WP, нас интересуют на данном этапе <strong>посты, страницы и поиск</strong>.</p>



<h4 class="wp-block-heading"><a href="https://developer.wordpress.org/rest-api/reference/#rest-api-developer-endpoint-reference" target="_blank" rel="noreferrer noopener" style="text-decoration:none;">REST API Developer Endpoint Reference</a></h4>



<figure class="wp-block-table"><table><tbody><tr><th>Resource</th><th>Base Route</th></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/posts/">Posts</a></td><td><code>/wp/v2/posts</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/post-revisions/">Post Revisions</a></td><td><code>/wp/v2/posts/&lt;id&gt;/revisions</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/categories/">Categories</a></td><td><code>/wp/v2/categories</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/tags/">Tags</a></td><td><code>/wp/v2/tags</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/pages/">Pages</a></td><td><code>/wp/v2/pages</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/page-revisions/">Page Revisions</a></td><td><code>/wp/v2/pages/&lt;id&gt;/revisions</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/comments/">Comments</a></td><td><code>/wp/v2/comments</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/taxonomies/">Taxonomies</a></td><td><code>/wp/v2/taxonomies</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/media/">Media</a></td><td><code>/wp/v2/media</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/users/">Users</a></td><td><code>/wp/v2/users</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/post-types/">Post Types</a></td><td><code>/wp/v2/types</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/post-statuses/">Post Statuses</a></td><td><code>/wp/v2/statuses</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/settings/">Settings</a></td><td><code>/wp/v2/settings</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/themes/">Themes</a></td><td><code>/wp/v2/themes</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/search-results/">Search</a></td><td><code>/wp/v2/search</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/block-types/">Block Types</a></td><td><code>/wp/v2/block-types</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/blocks/">Blocks</a></td><td><code>/wp/v2/blocks</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/block-revisions/">Block Revisions</a></td><td><code>/wp/v2/blocks/&lt;id&gt;/autosaves/</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/rendered-blocks/">Block Renderer</a></td><td><code>/wp/v2/block-renderer</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/block-directory-items/">Block Directory Items</a></td><td><code>/wp/v2/block-directory/search</code></td></tr><tr><td><a href="https://developer.wordpress.org/rest-api/reference/plugins/">Plugins</a></td><td><code>/wp/v2/plugins</code></td></tr></tbody></table></figure>



<p>Весь API находится в разделе /wp-json/, те для <strong>постов</strong> например это:</p>



<pre class="wp-block-code"><code class="">https://example.com/wp-json/wp/v2/posts </code></pre>



<p>В ответ получаем массив постов вида (отдается кол-во постов равное установленному ранее параметром <strong>pre_page</strong>, при его отсутствии в запросе):</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://consultapp.ru/wp-content/uploads/2023/06/image.png"><img fetchpriority="high" decoding="async" width="700" height="347" src="https://consultapp.ru/wp-content/uploads/2023/06/image-700x347.png" alt="" class="wp-image-1688" srcset="https://consultapp.ru/wp-content/uploads/2023/06/image-700x347.png 700w, https://consultapp.ru/wp-content/uploads/2023/06/image-300x149.png 300w, https://consultapp.ru/wp-content/uploads/2023/06/image-768x381.png 768w, https://consultapp.ru/wp-content/uploads/2023/06/image.png 1082w" sizes="(max-width: 700px) 100vw, 700px" /></a><figcaption class="wp-element-caption">Результат обращения к endpoint posts, на примере нашего сайта.</figcaption></figure></div>


<p>/* СТАТЬЯ В  РАЗРАБОТКЕ. */</p>
<p>Сообщение <a href="https://consultapp.ru/themelia-php-to-react-wordpress-headless-cms-no-ssr/">Переработка темы Themelia c PHP на React, для работы с WordPress в качестве Headless CMS без SSR</a> появились сначала на <a href="https://consultapp.ru">ConsultApp.ru</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Простая конфигурация Nginx для SPA  приложения без SSR</title>
		<link>https://consultapp.ru/%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%b0%d1%8f-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f-nginx-%d0%b4%d0%bb%d1%8f-spa-%d0%bf%d1%80%d0%b8%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%b8/</link>
		
		<dc:creator><![CDATA[Дмитрий]]></dc:creator>
		<pubDate>Sun, 04 Jun 2023 08:57:41 +0000</pubDate>
				<category><![CDATA[Nginx]]></category>
		<category><![CDATA[React JS]]></category>
		<category><![CDATA[Статьи]]></category>
		<guid isPermaLink="false">https://consultapp.ru/?p=1627</guid>

					<description><![CDATA[<p>Билд SPA приложения без SSR, в нашем случае это Vite.js + React, представляет собой набор статических файлов, с отдачей которых справится базовая настройка Nginx с минимальными изменениями. В нашем случае мы используем Webmin/Virtualmin для настройки, но это не особо влияет на саму конфигурацию. Для запуска SPA приложения на базовой конфигурации Nginx сервера, нам не хватает&#8230;</p>
<p>Сообщение <a href="https://consultapp.ru/%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%b0%d1%8f-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f-nginx-%d0%b4%d0%bb%d1%8f-spa-%d0%bf%d1%80%d0%b8%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%b8/">Простая конфигурация Nginx для SPA  приложения без SSR</a> появились сначала на <a href="https://consultapp.ru">ConsultApp.ru</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Билд SPA приложения без SSR, в нашем случае это Vite.js + React, представляет собой набор статических файлов, с отдачей которых справится базовая настройка Nginx с минимальными изменениями. </p>



<span id="more-1627"></span>



<p>В нашем случае мы используем Webmin/Virtualmin для настройки, но это не особо влияет на саму конфигурацию. </p>



<p>Для запуска SPA приложения на базовой конфигурации Nginx сервера, нам не хватает нескольких моментов:</p>



<ol class="wp-block-list">
<li>Переадресация всех путей на наш рут, <strong>/index.html </strong>в данном случае;</li>



<li>Зарезервированный путь для получения/обновления SSL сертификатов.</li>
</ol>



<h2 class="wp-block-heading">Переадресация путей</h2>



<p>Тут нам надо исправить 2 момента:</p>



<pre class="wp-block-code"><code lang="nginx" class="language-nginx">#Установим <strong>root и точку входа</strong>, у нас <strong>index.html</strong> в папка <strong>dist</strong>
root /home/my_domain/my_domain/dist/; 
index index.html;</code></pre>



<pre class="wp-block-code"><code lang="nginx" class="language-nginx"># Укажем, как обрабатывать пути, кроме статических файлов (отбор по расширениям)

location / {
        if (-f $request_filename) {
            	expires max;
            	break;
        }
        if ($request_filename !~ "\.(js|htc|ico|gif|jpg|png|css)$") {
            	rewrite ^(.*) /index.html last;
        }
}
</code></pre>



<h2 class="wp-block-heading">Получение/обновление SSL</h2>



<p>В данном случае мы используем Let&#8217;s Encrypt, Webmin для автоматической работы с этими сертификатами использует папку<strong> /.well-known</strong>, соответственно выделяем ее так, что бы она не обрабатывалась нашим SPA &#8212; например меняем для этого <strong>location</strong> <strong>root</strong>.</p>



<pre class="wp-block-code"><code lang="nginx" class="language-nginx">location /.well-known/ {
	root /home/my_domain/public_html;
}</code></pre>



<h2 class="wp-block-heading">Итоговый шаблон</h2>



<pre class="wp-block-code"><code lang="nginx" class="language-nginx line-numbers">server {
	server_name my_domain.ru www.my_domain.ru;

	# your server IP
	listen 00.00.00.00;

	root /home/my_domain/my_domain/dist/;
	index index.html;

	access_log /var/log/virtualmin/my_domain.ru_access_log;
	error_log /var/log/virtualmin/my_domain.ru_error_log;
	fastcgi_param GATEWAY_INTERFACE CGI/1.1;
	fastcgi_param SERVER_SOFTWARE nginx;
	fastcgi_param QUERY_STRING $query_string;
	fastcgi_param REQUEST_METHOD $request_method;
	fastcgi_param CONTENT_TYPE $content_type;
	fastcgi_param CONTENT_LENGTH $content_length;
	fastcgi_param SCRIPT_FILENAME /home/my_domain/public_html$fastcgi_script_name;
	fastcgi_param SCRIPT_NAME $fastcgi_script_name;
	fastcgi_param REQUEST_URI $request_uri;
	fastcgi_param DOCUMENT_URI $document_uri;
	fastcgi_param DOCUMENT_ROOT /home/my_domain/public_html;
	fastcgi_param SERVER_PROTOCOL $server_protocol;
	fastcgi_param REMOTE_ADDR $remote_addr;
	fastcgi_param REMOTE_PORT $remote_port;
	fastcgi_param SERVER_ADDR $server_addr;
	fastcgi_param SERVER_PORT $server_port;
	fastcgi_param SERVER_NAME $server_name;
	fastcgi_param PATH_INFO $fastcgi_path_info;
	fastcgi_param HTTPS $https;

	location /.well-known/ {
		root /home/my_domain/public_html;
	}

	location / {
        	if (-f $request_filename) {
            		expires max;
            		break;
        	}

        	if ($request_filename !~ "\.(js|ico|gif|jpg|png|css)$") {
            		rewrite ^(.*) /index.html last;
        	}
    	}

	# your server IP
	listen 00.00.00.00:443 ssl;
	ssl_certificate /etc/ssl/virtualmin/PATH_TO_KEY/ssl.combined;
	ssl_certificate_key /etc/ssl/virtualmin/PATH_TO_KEY/ssl.key;
}
</code></pre>



<h2 class="wp-block-heading">Итого</h2>



<p>Очевидно, что все папки и адреса Вам необходимо заменить на собственные, но идея остается прежней: перехватываем все пути и замыкаем на <strong>index.html</strong>, а отдельные служебные пути выделяем в <strong>location</strong> и оставляем например в стандартной <strong>public_html</strong>  для удобства. </p>



<p>Так же при необходимости использования API с этого же сервера, Вы можете самостоятельно добавить <strong>location</strong> по типу <strong>/api/</strong> и сделать редирект на обработчик например.</p>
<p>Сообщение <a href="https://consultapp.ru/%d0%bf%d1%80%d0%be%d1%81%d1%82%d0%b0%d1%8f-%d0%ba%d0%be%d0%bd%d1%84%d0%b8%d0%b3%d1%83%d1%80%d0%b0%d1%86%d0%b8%d1%8f-nginx-%d0%b4%d0%bb%d1%8f-spa-%d0%bf%d1%80%d0%b8%d0%bb%d0%be%d0%b6%d0%b5%d0%bd%d0%b8/">Простая конфигурация Nginx для SPA  приложения без SSR</a> появились сначала на <a href="https://consultapp.ru">ConsultApp.ru</a>.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Запускаем Next.js приложение через PM2 на Nginx в простейшей конфигурации</title>
		<link>https://consultapp.ru/simple-start-next-js-app-with-pm2-on-nginx/</link>
		
		<dc:creator><![CDATA[Дмитрий]]></dc:creator>
		<pubDate>Tue, 20 Jul 2021 10:26:42 +0000</pubDate>
				<category><![CDATA[Next.js]]></category>
		<category><![CDATA[React JS]]></category>
		<category><![CDATA[Статьи]]></category>
		<category><![CDATA[next.js]]></category>
		<category><![CDATA[nginx]]></category>
		<category><![CDATA[pm2]]></category>
		<guid isPermaLink="false">https://consultapp.ru/?p=1348</guid>

					<description><![CDATA[<p>После написания нашего прекрасного веб приложения встает вопрос, как запустить его покорять мир (на рабочем сервере с доменом и прочим). Здесь нам и понадобится Nginx, тк мы хотим получить полноценный вебсервер и SSL в том числе. Для начала стоит отметить, что без SSL для тестовых запусков достаточно и npm run start на 80 порту &#8212;&#8230;</p>
<p>Сообщение <a href="https://consultapp.ru/simple-start-next-js-app-with-pm2-on-nginx/">Запускаем Next.js приложение через PM2 на Nginx в простейшей конфигурации</a> появились сначала на <a href="https://consultapp.ru">ConsultApp.ru</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>После написания нашего прекрасного веб приложения встает вопрос, как запустить его покорять мир (на рабочем сервере с доменом и прочим). Здесь нам и понадобится  Nginx, тк мы хотим получить полноценный вебсервер и SSL в том числе.</p>



<span id="more-1348"></span>



<p>Для начала стоит отметить, что без SSL для тестовых запусков достаточно и <strong>npm run start</strong> на 80 порту &#8212; все заработает из коробки, ну почти, если домен напрямую прокинут на айпишники и в нашем распоряжении целый отдельный сервер.</p>



<h2 class="wp-block-heading">Схема работы</h2>



<p>Наша схема работы будет выглядеть максимально просто:</p>



<ol class="wp-block-list">
<li>Nginx  висит, как и подобает вебсерверу, на 80 и 443 портах, обеспечивая маршрутизацию и SSL;</li>



<li>Запросы мы проксируем на localhost с нужным портом, например 3000, тк он у нас по дефолту Next.</li>
</ol>



<h2 class="wp-block-heading">Nginx</h2>



<p>Для простоты мы будем править напрямую основной конфигурационный файл<strong>  /etc/nginx/nginx.conf</strong>, как Вы понимаете на рабочем проекте так делать не надо &#8212; разберитесь с &nbsp;папками /etc/nginx/sites-available/ и /etc/nginx/sites-enabled.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">nano /etc/nginx/nginx.conf</code></pre>



<p>Как установить Nginx , подробно описано на <a href="https://www.nginx.com/resources/wiki/start/topics/tutorials/install/" target="_blank" rel="noreferrer noopener nofollow">официальном сайте</a>, все зависит от Вашей операционной системы очевидно.</p>



<p>Итак, наши настройки для сервера (выжимка), естественно *_INSERT_IP_ADRESS_* надо заменить на Ваш ip сервера и our_best_site на Ваш домен и всю структуру папок проверить (/home/our_best_site/public_html и тд):</p>



<pre class="wp-block-code"><code lang="nginx" class="language-nginx">server {
                server_name our_best_site.ru www.our_best_site.ru;
                listen *_INSERT_IP_ADRESS_*;
                root /home/our_best_site/public_html;
                index index.php index.htm index.html;
                access_log /var/log/virtualmin/our_best_site.ru_access_log;
                error_log /var/log/virtualmin/our_best_site.ru_error_log;
                fastcgi_param GATEWAY_INTERFACE CGI/1.1;
                fastcgi_param SERVER_SOFTWARE nginx;
                fastcgi_param QUERY_STRING $query_string;
                fastcgi_param REQUEST_METHOD $request_method;
                fastcgi_param CONTENT_TYPE $content_type;
                fastcgi_param CONTENT_LENGTH $content_length;
                fastcgi_param SCRIPT_FILENAME /home/our_best_site/public_html$fastcgi_script_name;
                fastcgi_param SCRIPT_NAME $fastcgi_script_name;
                fastcgi_param REQUEST_URI $request_uri;
                fastcgi_param DOCUMENT_URI $document_uri;
                fastcgi_param DOCUMENT_ROOT /home/our_best_site/public_html;
                fastcgi_param SERVER_PROTOCOL $server_protocol;
                fastcgi_param REMOTE_ADDR $remote_addr;
                fastcgi_param REMOTE_PORT $remote_port;
                fastcgi_param SERVER_ADDR $server_addr;
                fastcgi_param SERVER_PORT $server_port;
                fastcgi_param SERVER_NAME $server_name;
                fastcgi_param PATH_INFO $fastcgi_path_info;
                fastcgi_param HTTPS $https;

               <strong> location / {
                        proxy_pass http://localhost:3000/;
                }</strong>

                fastcgi_split_path_info ^(.+\.php)(/.+)$;
                listen *_INSERT_IP_ADRESS_*:443 ssl;
                <strong>ssl_certificate /home/our_best_site/ssl.combined;
                ssl_certificate_key /home/our_best_site/ssl.key;</strong>
        }</code></pre>



<p>У Nginx куча настроек и улучшать можно постоянно, но основная магия в паре строк, те мы проксируем все запросы на &#171;/&#187; на наш node сервер, который мы скоро запустим:</p>



<pre class="wp-block-code"><code lang="nginx" class="language-nginx">location / {<br>proxy_pass http://localhost:3000/;<br>}</code></pre>



<p>Для работы SSL, нам надо получить сертификаты в сертификационном центре и указать пути к этим файлам:</p>



<pre class="wp-block-code"><code lang="nginx" class="language-nginx">ssl_certificate /home/our_best_site/ssl.combined;
ssl_certificate_key /home/our_best_site/ssl.key;</code></pre>



<h2 class="wp-block-heading">Запускаем приложение</h2>



<h3 class="wp-block-heading">Какие файлы нам нужны от Next.js для запуска?</h3>



<p>Для начала нам нужно запустить в терминале компиляцию проекта <strong>npm run build</strong>, в итоге мы увидим что-то похожее. Next создаст все необходимые файлы, статические и для рендеринга на сервере.</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://consultapp.ru/wp-content/uploads/2021/07/image.png"><img decoding="async" width="626" height="318" src="https://consultapp.ru/wp-content/uploads/2021/07/image.png" alt="" class="wp-image-1352" srcset="https://consultapp.ru/wp-content/uploads/2021/07/image.png 626w, https://consultapp.ru/wp-content/uploads/2021/07/image-300x152.png 300w" sizes="(max-width: 626px) 100vw, 626px" /></a></figure></div>


<p>Осталось понять, что же нам нужно перенести на рабочий сервер в простейшем варианте, без Git и прочих полезных вещей. </p>



<p>Мы идем на сервер, создаем рабочую папку для Next и копируем туда файлы и папки:</p>



<ol class="wp-block-list">
<li><strong>/.next</strong> &#8212; основная рабочая папка;</li>



<li><strong>/public</strong>  &#8212; папка со статическими публичными файлами, например favicon.ico и robots.txt;</li>



<li><strong>next.config.js</strong> &#8212; конфигурационный файл next, куда надо не забыть включить домены для картинок и например webpack5: true;</li>



<li><strong>package.json</strong> &#8212; конфигурационный файл приложения.</li>
</ol>



<p>Далее осталось запустить в этой папке <strong>npm install</strong>, при этом менеджер проанализирует package.json и автоматически сгенерирует папку <strong>/node_modules</strong>, со всеми необходимыми пакетами. Ее не надо копировать из среды разработки.</p>



<p>Все, теперь достаточно запустить <strong>npm run start</strong> или любой нужный скрипт из package.json и, если Вы правильно указали порт, а у нас Nginx проксирует на 3000, все заработает. Но, это неудобно, тк стоит закрыть терминал &#8212; все умрет. Эту проблемы нам поможет решить отличный менеджер процессов PM2.</p>



<h3 class="wp-block-heading">Запускаем Nextjs через PM2 (менеджер процессов)</h3>



<p>Подробно прочитать про этот менеджер процессов можно в мануале на <a href="https://pm2.keymetrics.io/" target="_blank" rel="noreferrer noopener nofollow">официальном сайте</a>, мы же укажем только необходимый минимум</p>



<p>Итак, устанавливаем pm2 командой (возможно Вам потребуется использовать <strong>sudo</strong>):</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">npm install pm2 -g</code></pre>



<h4 class="wp-block-heading">Запуск процессов</h4>



<p>Для запуска проекта в простом варианте можно использовать что-то вроде, при этом не забудьте перейти в рабочую папку проекта nextjs.</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">pm2 start npm -- start</code></pre>



<p>А так же полезные ключи:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash"># Указываем имя запущенного приложения
--name &lt;app_name&gt;

# Устанавливаем наблюдение за файлами проекта и перезапускаем приложение при их изменении
--watch

# Устанавливаем лимит памяти до перезагрузки приложения
--max-memory-restart &lt;200MB&gt;

# Определяем путь к файлу логов
--log &lt;log_path&gt;

# Прокидываем аргументы в скрипт
-- arg1 arg2 arg3

# Задержка между автоматическими перезапусками
--restart-delay &lt;delay in ms&gt;

# Добавлять префикс времени в логах
--time

# Не перезапускать автоматически приложение
--no-autorestart

# Определяем задачу крон для принудительного перезапуска (<code>forced</code> restart)
--cron &lt;cron_pattern&gt;</code></pre>



<h4 class="wp-block-heading">Управление и мониторинг процессов</h4>



<p>Для управления запущенными процессами можно использовать команды:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">$ pm2 restart app_name
$ pm2 reload app_name
$ pm2 stop app_name
$ pm2 delete app_name</code></pre>



<p>Вместо app_name можно использовать:</p>



<ul class="wp-block-list">
<li><code><strong>all</strong></code>&nbsp;для управления всеми процессами;</li>



<li><code><strong>id</strong></code>&nbsp;для управления процессом по его id.</li>
</ul>



<p>Мониторить запущенные процессы можно парой удобных команд:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">// онлайн мониторинг в экране терминала
$ pm2 monit

// список процессов
# pm2 list</code></pre>



<p>Пример вывода для <strong>pm2 monit</strong>:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://consultapp.ru/wp-content/uploads/2021/07/image-2.png"><img decoding="async" width="585" height="374" src="https://consultapp.ru/wp-content/uploads/2021/07/image-2.png" alt="Команда pm2 monit" class="wp-image-1359" srcset="https://consultapp.ru/wp-content/uploads/2021/07/image-2.png 585w, https://consultapp.ru/wp-content/uploads/2021/07/image-2-300x192.png 300w" sizes="(max-width: 585px) 100vw, 585px" /></a></figure></div>


<h4 class="wp-block-heading">Итого по pm2</h4>



<p>Теперь мы можем запустить наш проект, со всеми ключами. Представим, что наше приложение лежит в папке <strong>/home/our_best_site/public_html/nextjs</strong>:</p>



<pre class="wp-block-code"><code lang="bash" class="language-bash">$ cd /home/our_best_site/public_html/nextjs
$ pm2 start npm --watch --ignore-watch="node_modules" --restart-delay=10000 --name "app_name1" -- start</code></pre>



<p>Из строки видно, что запускаем мы в рабочей папке наш процесс <strong>npm start</strong> с именем <strong>app_name1</strong>, при этом следим за изменениями с задержкой перезапуска <strong>10000мс</strong> и игнорируем папку <strong>node_modules</strong>. </p>



<p>При этом в терминале мы увидим наше приложение:</p>


<div class="wp-block-image">
<figure class="aligncenter size-large"><a href="https://consultapp.ru/wp-content/uploads/2021/07/image-1.png"><img loading="lazy" decoding="async" width="558" height="68" src="https://consultapp.ru/wp-content/uploads/2021/07/image-1.png" alt="Команда pm2 start npm  --name &quot;app_name1&quot; -- start" class="wp-image-1358" srcset="https://consultapp.ru/wp-content/uploads/2021/07/image-1.png 558w, https://consultapp.ru/wp-content/uploads/2021/07/image-1-300x37.png 300w" sizes="auto, (max-width: 558px) 100vw, 558px" /></a></figure></div>


<h2 class="wp-block-heading">Заключение</h2>



<p>В результате мы получаем nextjs приложение, которое работает на 3000 порту и все запросы (80 и 443 портов) в него проксируются через nginx. Управление приложением происходит через менеджер <strong>pm2</strong>.  Стоит отметить, что все написанное будет работать и для React.js приложения с минимальными правками. </p>



<p>Ура, все работает)</p>
<p>Сообщение <a href="https://consultapp.ru/simple-start-next-js-app-with-pm2-on-nginx/">Запускаем Next.js приложение через PM2 на Nginx в простейшей конфигурации</a> появились сначала на <a href="https://consultapp.ru">ConsultApp.ru</a>.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
