{"record":{"id":"79bc34a35c21c514","repo":"ViewComponent/view_component","slug":"a-preview-template-for-example-example-doesn-t-exi","errorCode":null,"errorMessage":"A preview template for example EXAMPLE doesn't exist.\n\nTo fix this issue, create a template for the example.","messagePattern":"A preview template for example EXAMPLE doesn't exist\\.\n\nTo fix this issue, create a template for the example\\.","errorType":"exception","errorClass":"ViewComponent::MissingPreviewTemplateError","httpStatus":null,"severity":"error","filePath":"lib/view_component/preview.rb","lineNumber":88,"sourceCode":"      def preview_name\n        name.chomp(\"Preview\").underscore\n      end\n\n      # rubocop:disable Style/TrivialAccessors\n      # Setter for layout name.\n      def layout(layout_name)\n        @layout = layout_name\n      end\n      # rubocop:enable Style/TrivialAccessors\n\n      # Returns the relative path (from preview_path) to the preview example template if the template exists\n      def preview_example_template_path(example)\n        preview_path =\n          Array(preview_paths).detect do |path|\n            Dir[\"#{path}/#{preview_name}_preview/#{example}.html.*\"].first\n          end\n\n        raise MissingPreviewTemplateError.new(example) if preview_path.nil?\n\n        path = Dir[\"#{preview_path}/#{preview_name}_preview/#{example}.html.*\"].first\n        Pathname.new(path)\n          .relative_path_from(Pathname.new(preview_path))\n          .to_s\n          .sub(/\\..*$/, \"\")\n      end\n\n      # @private\n      def __vc_load_previews\n        Array(preview_paths).each do |preview_path|\n          Dir[\"#{preview_path}/**/*preview.rb\"].sort.each { |file| require file }\n        end\n      end\n\n      private\n\n      def preview_paths","sourceCodeStart":70,"sourceCodeEnd":106,"githubUrl":"https://github.com/ViewComponent/view_component/blob/9f22c36fa7d7b44098a8ed97472e3b4674ae420f/lib/view_component/preview.rb#L70-L106","documentation":"When a preview example method returns nil (or a hash without a :template key), render_args falls back to looking up a template file at <preview_path>/<preview_name>_preview/<example>.html.* across Base.previews.paths. If no such file exists in any preview path, preview_example_template_path raises ViewComponent::MissingPreviewTemplateError. The fix is either to return a render hash from the example or to provide the template file.","triggerScenarios":"A preview example whose body is empty or returns nil (def default; end) with no previews/<name>_preview/<example>.html.erb file; example methods that only set up fixtures and forget render(...); preview_paths (ViewComponent::Base.previews.paths, default test/components/previews) not including the directory where the template lives.","commonSituations":"Scaffolding a new preview and forgetting either the render call or the template; moving preview templates during a directory restructure so the Dir[] glob no longer matches; setups where previews live in spec/components/previews but only test/components/previews is configured.","solutions":["Make the example method return a render call: def default; render(UserComponent.new); end — then no template file is needed.","Or create the preview template file at <preview_path>/user_preview/default.html.erb (matching preview_name_preview/<example>.html.*).","Verify config: Rails.application.config.view_component.preview_paths actually contains the directory holding the template.","Check the file name matches the example method exactly (default.html.erb for def default)."],"exampleFix":"# before\nclass UserPreview < ViewComponent::Preview\n  def default\n    # returns nil -> falls back to template lookup -> MissingPreviewTemplateError\n  end\nend\n\n# after\nclass UserPreview < ViewComponent::Preview\n  def default\n    render(UserComponent.new(user: users(:one)))\n  end\nend","handlingStrategy":"validation","validationCode":"example = \"default\"\nhas_template = Array(ViewComponent::Base.previews.paths).any? do |p|\n  Dir[\"#{p}/#{UserPreview.preview_name}_preview/#{example}.html.*\"].any?\nend\n\nraise ArgumentError, \"need render(...) or a template file\" unless has_template || UserPreview.new.respond_to?(example)","typeGuard":null,"tryCatchPattern":"begin\n  UserPreview.render_args(example)\nrescue ViewComponent::MissingPreviewTemplateError\n  render html: \"Create previews/#{UserPreview.preview_name}_preview/#{example}.html.erb\", status: :not_found\nend","preventionTips":["End every preview example with an explicit render(...) call — never rely on the nil fallback.","Add a CI spec asserting each preview example either returns a render hash or has a matching template file under preview_paths.","Keep preview template directories in sync with preview_paths config after restructures."],"tags":["view-component","ruby-on-rails","previews","missing-template","dev-tooling"],"backgroundTag":"missing-template","analyzedSha":"9f22c36fa7d7b44098a8ed97472e3b4674ae420f","analyzedAt":"2026-08-23T10:20:47.008Z","schemaVersion":2},"datasetVersion":"2026-08-23T13:39:53.451Z"}