{"id":140088,"date":"2024-04-02T12:27:42","date_gmt":"2024-04-02T12:27:42","guid":{"rendered":"https:\/\/learn.wordpress.org\/?post_type=lesson&#038;p=140088"},"modified":"2025-05-13T08:24:14","modified_gmt":"2025-05-13T08:24:14","slug":"building-your-first-block","status":"publish","type":"lesson","link":"https:\/\/learn.wordpress.org\/lesson\/building-your-first-block\/","title":{"rendered":"Building your first block"},"content":{"rendered":"\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"Building your first block\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/lxyeE_jZbts?feature=oembed&#038;enablejsapi=1&#038;origin=https:\/\/learn.wordpress.org\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n<div class=\"sensei-block-wrapper\">\n<div class=\"wp-block-sensei-lms-lesson-actions\"><div class=\"sensei-buttons-container\">\n\n\n\n\n\n<\/div><\/div>\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">Once you&#8217;ve scaffolded your block using <code>create-block<\/code>, you can start tweaking the code to meet your requirements.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Let&#8217;s dive into what this might look like for the Copyright Date Block you scaffolded in the previous lesson.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Clean up<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">To start, you can clean up any scaffolded code you don&#8217;t need.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Navigate to the <code>copyright-date-block\/src<\/code> directory and remove the <code>view.js<\/code> file. At the same time, remove the <code>viewScript<\/code> property from the block.json. Make sure not to leave a trailing comma at the end of the last property in the block.json file.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">The main plugin file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now open the <code>copyright-date-block.php<\/code> file in the root of the plugin directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">There&#8217;s not a lot to be changed in this file, except maybe the <code>@package<\/code> annotation in the plugin header. This defaults to <code>create-block<\/code>, and you might want to change it to something more specific to your plugin.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">For the purposes of this lesson, let&#8217;s change it to <code>copyright-date<\/code>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You can also improve the code that registers the block, by moving the hook registration above the <code>init<\/code> hook&#8217;s callback, and simplifying the callback function name.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"php\" class=\"language-php\">add_action( 'init', 'copyright_date_copyright_date_block_block_init' );\nfunction copyright_date_copyright_date_block_block_init() {\n    register_block_type( __DIR__ . '\/build\/copyright-date-block' );\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This makes this code a little easier to read and understand.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">As you can see the code uses the <code>register_block_type<\/code> function to register the block, which use the metadata from the <code>block.json<\/code> file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Therefore, now would be a good time to review the <code>block.json<\/code> file.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Block Metadata<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>block.json<\/code> file contains the block metadata, in a JSON format.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n    \"$schema\": \"https:\/\/schemas.wp.org\/trunk\/block.json\",\n    \"apiVersion\": 3,\n    \"name\": \"create-block\/copyright-date-block\",\n    \"version\": \"0.1.0\",\n    \"title\": \"Copyright Date Block\",\n    \"category\": \"widgets\",\n    \"icon\": \"smiley\",\n    \"description\": \"Example block scaffolded with Create Block tool.\",\n    \"example\": {},\n    \"supports\": {\n        \"html\": false\n    },\n    \"textdomain\": \"copyright-date-block\",\n    \"editorScript\": \"file:.\/index.js\",\n    \"editorStyle\": \"file:.\/index.css\",\n    \"style\": \"file:.\/style-index.css\"\n}<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">JSON stands for <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Learn\/JavaScript\/Objects\/JSON\">JavaScript Object Notation<\/a>, and it&#8217;s a lightweight data format that is easy for humans to read and write and easy for machines to parse and generate.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">JSON is made up of key-value pairs, and each value can also be a nested JSON object.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To modify the scaffolded block metadata for your block, you should change at least the values of the following properties:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>update the <code>name<\/code>. In this case you can replace <code>create-block<\/code> with the same value you used for the package value in the plugin header, <code>copyright-date<\/code>.<\/li>\n\n\n\n<li>update the <code>icon<\/code>. For now, change the <code>icon<\/code> value to <code>calendar<\/code>. This icon comes from the <a href=\"https:\/\/wordpress.github.io\/gutenberg\/?path=\/story\/icons-icon--library\">Gutenberg Icon Library<\/a>.<\/li>\n\n\n\n<li>update the <code>description<\/code>, to make it more specific to your block.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Your <code>block.json<\/code> file should look something like this:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"json\" class=\"language-json\">{\n  \"$schema\": \"https:\/\/schemas.wp.org\/trunk\/block.json\",\n  \"apiVersion\": 3,\n  \"name\": \"copyright-date\/copyright-date-block\",\n  \"version\": \"0.1.0\",\n  \"title\": \"Copyright Date Block\",\n  \"category\": \"widgets\",\n  \"icon\": \"calendar\",\n  \"description\": \"A Copyright Date block.\",\n  \"example\": {},\n  \"supports\": {\n    \"html\": false\n  },\n  \"textdomain\": \"copyright-date-block\",\n  \"editorScript\": \"file:.\/index.js\",\n  \"editorStyle\": \"file:.\/index.css\",\n  \"style\": \"file:.\/style-index.css\"\n}<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">The block&#8217;s main JavaScript file<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The <code>index.js<\/code> file in the <code>src<\/code> directory is the main JavaScript file for your block. Mostly you won&#8217;t need to change much in this file, as it&#8217;s already set up to register your block for the block editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">At the top of the file you&#8217;ll see the following line:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"javascript\" class=\"language-javascript\">import { registerBlockType } from '@wordpress\/blocks';<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">The JavaScript <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/Reference\/Statements\/import\">import<\/a> declaration is used to import functionality (variables, functions, objects) from somewhere else.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">In this case, the code is importing the <code>registerBlockType<\/code> function from the <code>@wordpress\/blocks<\/code> package, which is the package that powers the Block Editor.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Next, it imports the <code>style.scss<\/code> file, which is the file that contains the block&#8217;s styles.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Then it imports the <code>Edit<\/code> component. This component is exported from the <code>edit.js<\/code> file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">After that, it imports the <code>save<\/code> function. This function is exported from the <code>save.js<\/code> file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Last, but not least, it imports the JSON object from the <code>block.json<\/code> file as the <code>metadata<\/code> variable.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Finally, it uses the <code>registerBlockType<\/code> function to register the block, and passes in two variables, the block name, and a block configuration object of block properties.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Inside the properties object, the <code>edit<\/code> property is set to the value of the <code>Edit<\/code> component, and the <code>save<\/code> property is set to the value of the <code>save<\/code> function. Because the <code>save<\/code> property and the imported <code>save<\/code> function have the same name, it uses a shorthand syntax to set the property value.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Your first build<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Now that you&#8217;ve updated some block code, you can build your block for the first time.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">To build your block, open a terminal and navigate to the root of your block plugin directory. Then run the following command:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">npm run build<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This will scan through the contents of your <code>src<\/code> directory, and compile the files from that directory into the <code>build<\/code> directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">If the <code>build<\/code> directory doesn&#8217;t exist, it will be created.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Whenever you make changes to your block code, you&#8217;ll need to run this command again to update the build directory.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Optionally, there is a <code>npm run start<\/code> command that will start a development server that watches for changes to the files in the <code>src<\/code> directory and automatically builds them into the <code>build<\/code> directory.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code lang=\"bash\" class=\"language-bash\">npm run start<\/code><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">This is useful for when you&#8217;re actively developing your block.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Whichever option you use, if you open your WordPress dashboard, create a new Post, and add your block, you should see the block in the block inserter.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">You&#8217;ll notice that the icon has changed, and the description is more specific to your block.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Additional resources<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">You can read more about the block metadata fields in the <a href=\"https:\/\/developer.wordpress.org\/block-editor\/reference-guides\/block-api\/block-metadata\/\">Metadata in block.json<\/a> section of the Block Editor Handbook, as well as the development platform and build processes in the <a href=\"https:\/\/developer.wordpress.org\/block-editor\/how-to-guides\/platform\/\">Development platform<\/a> and the <a href=\"https:\/\/developer.wordpress.org\/block-editor\/getting-started\/fundamentals\/javascript-in-the-block-editor\/\">Working with Javascript for the Block Editor<\/a> pages.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Building on the scaffolded code from the previous lesson, start customizing the block to meet the requirements<\/p>\n","protected":false},"featured_media":257103,"template":"","meta":{"advanced_seo_description":"","jetpack_seo_html_title":"","jetpack_seo_noindex":false,"_initial_content":"","_new_post":false,"_ef_editorial_meta_checkbox_code-shippet":"","_ef_editorial_meta_checkbox_gh-issue":"","_ef_editorial_meta_checkbox_tut-pass":"","_ef_editorial_meta_checkbox_callout-styling":"","_ef_editorial_meta_checkbox_brand":"","_ef_editorial_meta_checkbox_has-slides-in-browser":"","_ef_editorial_meta_checkbox_has-downloadable-slides":"","_ef_editorial_meta_checkbox_no-slides":"","_ef_editorial_meta_checkbox_included":"","_ef_editorial_meta_checkbox_image-alt-tags":"","expiration_date":"","language":"en_US","_duration":0,"presenter_wporg_username":[""],"other_contributor_wporg_username":[""],"video_url":"","_lesson_featured":"","_quiz_has_questions":false,"_lesson_complexity":"easy","_lesson_length":10,"_lesson_course":56187,"_lesson_preview":"preview"},"lesson-tag":[],"audience":[],"level":[6],"show":[],"wporg_wp_version":[],"wporg_included_content":[],"topic":[],"class_list":["post-140088","lesson","type-lesson","status-publish","has-post-thumbnail","hentry","module-an-introduction-to-developing-wordpress-blocks","level-beginner","post"],"is_coteacher":false,"jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/lessons\/140088","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/lessons"}],"about":[{"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/types\/lesson"}],"version-history":[{"count":6,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/lessons\/140088\/revisions"}],"predecessor-version":[{"id":291670,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/lessons\/140088\/revisions\/291670"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/media\/257103"}],"wp:attachment":[{"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/media?parent=140088"}],"wp:term":[{"taxonomy":"lesson-tag","embeddable":true,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/lesson-tag?post=140088"},{"taxonomy":"audience","embeddable":true,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/audience?post=140088"},{"taxonomy":"level","embeddable":true,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/level?post=140088"},{"taxonomy":"show","embeddable":true,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/show?post=140088"},{"taxonomy":"wporg_wp_version","embeddable":true,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/wporg_wp_version?post=140088"},{"taxonomy":"wporg_included_content","embeddable":true,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/wporg_included_content?post=140088"},{"taxonomy":"topic","embeddable":true,"href":"https:\/\/learn.wordpress.org\/wp-json\/wp\/v2\/topic?post=140088"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}