diff --git a/pkg/setup/item.go b/pkg/setup/item.go
index 12ba05f5e0d2b4c2391c2f62d369e0488e714402..1953cf09b332b5e39c1558c5e80fbe803c51a8b8 100644
--- a/pkg/setup/item.go
+++ b/pkg/setup/item.go
@@ -26,7 +26,7 @@ type (
 	ItemOption = EntityOption[ItemConf, *items.Item]
 
 	ItemConf struct {
-		PublishFunc func(s *Setup, item *items.Item) (*items.Item, bool)
+		PublishFunc func(s *Setup, item *items.Item, exists bool) (*items.Item, bool)
 		encoded     bool // Если запись загружена из файла, необходимо выполнить Decode перед установкой
 	}
 )
@@ -45,17 +45,26 @@ func (ItemConf) Init(e *Entity[ItemConf, *items.Item]) {
 	DeleteItemIfRemoveFlag()(e)
 }
 
-// OverwriteItem перезаписывает элемент
+// PublishItem публикует элемент.
 func PublishItem() ItemOption {
 	return func(c *Item) {
-		c.Conf.PublishFunc = func(s *Setup, item *items.Item) (*items.Item, bool) { return item, true }
+		c.Conf.PublishFunc = func(_ *Setup, item *items.Item, _ bool) (*items.Item, bool) { return item, true }
+	}
+}
+
+// PublishItemIfNotExists публикует элемент, если он отсутствовал в системе.
+func PublishItemIfNotExists() ItemOption {
+	return func(c *Item) {
+		c.Conf.PublishFunc = func(_ *Setup, item *items.Item, exists bool) (*items.Item, bool) {
+			return item, !exists
+		}
 	}
 }
 
 // DraftItem не публикует элемент, сохраняет его в черновике
 func DraftItem() ItemOption {
 	return func(c *Item) {
-		c.Conf.PublishFunc = func(s *Setup, item *items.Item) (*items.Item, bool) { return item, false }
+		c.Conf.PublishFunc = func(_ *Setup, item *items.Item, _ bool) (*items.Item, bool) { return item, false }
 	}
 }
 
@@ -149,7 +158,9 @@ func (s *Setup) InstallItem(ctx context.Context, exists map[string]*items.Item,
 	exist, itemExists := exists[item.ID]
 	// Если элемент не существует, создаем его
 	if !itemExists {
-		if item, publish := c.Conf.PublishFunc(s, item); publish {
+		var publish bool
+		item, publish = c.Conf.PublishFunc(s, item, itemExists)
+		if publish {
 			return items.CreateAndPublishItem(ctx, s.content.Items, item)
 		}
 		if _, err := s.content.Items.Create(ctx, item); err != nil {
@@ -160,7 +171,7 @@ func (s *Setup) InstallItem(ctx context.Context, exists map[string]*items.Item,
 
 	// Если элемент существует, обновляем его
 	if item, changed := c.UpdateFunc(s, exist, item); changed {
-		if _, publish := c.Conf.PublishFunc(s, item); publish {
+		if _, publish := c.Conf.PublishFunc(s, item, itemExists); publish {
 			return items.UpdateAndPublishItem(ctx, s.content.Items, item)
 		}
 		if err := s.content.Items.Update(ctx, item); err != nil {
diff --git a/pkg/setup/item_test.go b/pkg/setup/item_test.go
index 0a128625e7871d20aad0bceff7561197e97c01ea..22461a05d142f20f3c6c22e6ea73c99d1a87ea02 100644
--- a/pkg/setup/item_test.go
+++ b/pkg/setup/item_test.go
@@ -359,3 +359,107 @@ func TestSetup_UpdateDraft(t *testing.T) {
 		})
 	}
 }
+
+func TestPublishItemIfNotExists(t *testing.T) {
+	tests := []struct {
+		name      string
+		items     []*items.Item
+		itemsCall func(svc *itemsMock.Items)
+		wantErr   assert.ErrorAssertionFunc
+	}{
+		{
+			name: "Item not exists",
+			items: []*items.Item{
+				{
+					ID:           "1",
+					SpaceID:      "space",
+					EnvID:        "env",
+					CollectionID: "coll",
+					Data:         map[string]any{"text": "test"},
+				},
+			},
+			itemsCall: func(svc *itemsMock.Items) {
+				svc.On("Find", mock.Anything, mock.Anything, mock.Anything, mock.Anything,
+					mock.Anything, mock.Anything).Return(nil, 0, nil).Once()
+				svc.On("Create", mock.Anything, &items.Item{
+					ID:           "1",
+					SpaceID:      "space",
+					EnvID:        "env",
+					CollectionID: "coll",
+					Data:         map[string]any{"text": "test"},
+				}).Return(&items.Item{
+					ID:           "1",
+					SpaceID:      "space",
+					EnvID:        "env",
+					CollectionID: "coll",
+					Data:         map[string]any{"text": "test"},
+				}, nil).Once()
+				svc.On("Publish", mock.Anything, &items.Item{
+					ID:           "1",
+					SpaceID:      "space",
+					EnvID:        "env",
+					CollectionID: "coll",
+					Data:         map[string]any{"text": "test"},
+				}).Return(nil).Once()
+			},
+			wantErr: assert.NoError,
+		},
+		{
+			name: "Item exists",
+			items: []*items.Item{
+				{
+					ID:           "1",
+					SpaceID:      "space",
+					EnvID:        "env",
+					CollectionID: "coll",
+					Data:         map[string]any{},
+				},
+			},
+			itemsCall: func(svc *itemsMock.Items) {
+				svc.On("Find", mock.Anything, mock.Anything, mock.Anything,
+					mock.Anything, mock.Anything, mock.Anything).
+					Return([]*items.Item{{
+						ID:           "1",
+						SpaceID:      "space",
+						EnvID:        "env",
+						CollectionID: "coll",
+						Data:         map[string]any{"text": "test"},
+					}}, 1, nil).Once()
+				svc.On("Update", mock.Anything, &items.Item{
+					ID:           "1",
+					SpaceID:      "space",
+					EnvID:        "env",
+					CollectionID: "coll",
+					Data:         map[string]any{},
+				}).Return(nil).Once()
+				svc.On("Unpublish", mock.Anything, &items.Item{
+					ID:           "1",
+					SpaceID:      "space",
+					EnvID:        "env",
+					CollectionID: "coll",
+					Data:         map[string]any{},
+				}).Return(nil).Once()
+			},
+			wantErr: assert.NoError,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			svc := itemsMock.NewItems(t)
+			if tt.itemsCall != nil {
+				tt.itemsCall(svc)
+			}
+
+			s := NewSetup(&content.Content{Items: svc}, "space", "env", nil)
+			s.AddItems(
+				tt.items,
+				PublishItemIfNotExists(),
+				// Добавляем опцию обновления для проверки публикации, когда элемент уже существует
+				func(c *Entity[ItemConf, *items.Item]) {
+					c.UpdateFunc = func(_ *Setup, _, item *items.Item) (*items.Item, bool) { return item, true }
+				},
+			)
+			tt.wantErr(t, s.InstallItems(context.Background()))
+		})
+	}
+}