Creating a Wp Angular Theme for WordPress with Gutenberg

Building a bespoke Wp Angular theme offers the benefits of a modern JavaScript framework while maintaining the rich ecosystem and content management features of WordPress. The key challenge in this setup is ensuring full compatibility with Gutenberg blocks, the native WordPress block. This article walks through the process of integrating Angular in a WordPress theme and ensuring Gutenberg blocks remain fully functional.

Why Use Angular in a WordPress Theme?

Angular provides robust architecture, modular components, and reactive data handling. When integrated into WordPress, Angular can enhance the frontend experience, making it ideal for Spas (Single Page Applications) or highly interactive UIs.

Goals of This Integration

Build a custom WordPress theme using Angular.

Allow WordPress content ORS to use Gutenberg blocks as usual.

Render Gutenberg blocks properly inside the Angular-based theme.

Prerequisites

Familiarity with Angular and WordPress theme structure.
Node.js, Angular CLI, PHP, and WordPress are installed.
A WordPress development environment (like Local by Flywheel, MAMP, etc.).

Step 1: Create a New Angular Project

Create an Angular application using the Angular CLI:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
ng new angular-wp-theme
cd angular-wp-theme
ng build --output-path=dist
ng new angular-wp-theme cd angular-wp-theme ng build --output-path=dist
ng new angular-wp-theme
cd angular-wp-theme
ng build --output-path=dist

You can later build this with ng build– watch or ng build– configuration production.

Step 2: Set Up a WordPress Theme Structure

Create a new theme directory in your WordPress installation:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/wp-content/themes/angular-theme/
/wp-content/themes/angular-theme/
/wp-content/themes/angular-theme/

Inside this theme folder, create basic WordPress theme files:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
style.css
index.php
functions.php
header.php
footer.php
style.css (at minimum):
style.css index.php functions.php header.php footer.php style.css (at minimum):
style.css
index.php
functions.php
header.php
footer.php
style.css (at minimum):

 

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
css
/*
Theme Name: Angular WP Theme
*/
css /* Theme Name: Angular WP Theme */
css

/*
Theme Name: Angular WP Theme
*/

Step 3: Enqueue Angular Assets in functions.php

After building your Angular app, everything from /dist/angular-wp-theme/ into your theme directory under /assets/.

Then enqueue the JS and CSS in functions.php:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
function angular_theme_scripts() {
wp_enqueue_style('angular-style', get_template_directory_uri() . '/assets/styles.css');
wp_enqueue_script('angular-runtime', get_template_directory_uri() . '/assets/runtime.js', [], null, true);
wp_enqueue_script('angular-polyfills', get_template_directory_uri() . '/assets/polyfills.js', [], null, true);
wp_enqueue_script('angular-main', get_template_directory_uri() . '/assets/main.js', [], null, true);
}
add_action('wp_enqueue_scripts', 'angular_theme_scripts');
?>
<?php function angular_theme_scripts() { wp_enqueue_style('angular-style', get_template_directory_uri() . '/assets/styles.css'); wp_enqueue_script('angular-runtime', get_template_directory_uri() . '/assets/runtime.js', [], null, true); wp_enqueue_script('angular-polyfills', get_template_directory_uri() . '/assets/polyfills.js', [], null, true); wp_enqueue_script('angular-main', get_template_directory_uri() . '/assets/main.js', [], null, true); } add_action('wp_enqueue_scripts', 'angular_theme_scripts'); ?>
<?php

function angular_theme_scripts() {
wp_enqueue_style('angular-style', get_template_directory_uri() . '/assets/styles.css');
wp_enqueue_script('angular-runtime', get_template_directory_uri() . '/assets/runtime.js', [], null, true);
wp_enqueue_script('angular-polyfills', get_template_directory_uri() . '/assets/polyfills.js', [], null, true);
wp_enqueue_script('angular-main', get_template_directory_uri() . '/assets/main.js', [], null, true);
}
add_action('wp_enqueue_scripts', 'angular_theme_scripts');

?>

Step 4: Enable Gutenberg Compatibility

WordPress renders Gutenberg blocks using the_content(). To ensure compatibility:

In index.php or a relevant template:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php get_header(); ?>
<div id="angular-root">
<main>
<div id="wp-content">
<?php
while (have_posts()) : the_post();
the_content();
endwhile;
?>
</div>
</main>
</div>
<?php get_footer(); ?>
<?php get_header(); ?> <div id="angular-root"> <main> <div id="wp-content"> <?php while (have_posts()) : the_post(); the_content(); endwhile; ?> </div> </main> </div> <?php get_footer(); ?>
<?php get_header(); ?>
<div id="angular-root">
  <main>
    <div id="wp-content">
      <?php
      while (have_posts()) : the_post();
          the_content();
      endwhile;
      ?>
    </div>
  </main>
</div>
<?php get_footer(); ?>

 

In Angular, bootstrap inside angular-root
Angular should not overwrite the inner #wp-content block directly — instead, treat it as dynamic content.

You can fetch or manipulate content via:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Typescript
ngAfterViewInit() {
const content = document.getElementById('wp-content');
// Manipulate or interact as needed
}
Typescript ngAfterViewInit() { const content = document.getElementById('wp-content'); // Manipulate or interact as needed }
Typescript

ngAfterViewInit() {
const content = document.getElementById('wp-content');
// Manipulate or interact as needed
}

Step 5: Optional – REST API Integration

If you prefer fetching posts via Angular instead of using the_content(), use the WordPress REST API:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
Typescript
this.http.get('https://your-site.com/wp-json/wp/v2/posts').subscribe(posts => {
console.log(posts);
});
Typescript this.http.get('https://your-site.com/wp-json/wp/v2/posts').subscribe(posts => { console.log(posts); });
Typescript

this.http.get('https://your-site.com/wp-json/wp/v2/posts').subscribe(posts => {
console.log(posts);
});

Step 6: Keep Gutenberg Blocks Styled

Gutenberg blocks rely on core styles to appear correctly. You can include them by enqueuing:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
function angular_theme_support() {
add_theme_support('wp-block-styles');
add_theme_support('or-styles');
add_or_style('style.css');
}
add_action('after_setup_theme', 'angular_theme_support');
?>
<?php function angular_theme_support() { add_theme_support('wp-block-styles'); add_theme_support('or-styles'); add_or_style('style.css'); } add_action('after_setup_theme', 'angular_theme_support'); ?>
<?php

function angular_theme_support() {
add_theme_support('wp-block-styles');
add_theme_support('or-styles');
add_or_style('style.css');
}
add_action('after_setup_theme', 'angular_theme_support');

?>

And optionally load:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
wp_enqueue_style('wp-block-library');
?>
<?php wp_enqueue_style('wp-block-library'); ?>
<?php

wp_enqueue_style('wp-block-library');

?>

To make sure default Gutenberg styles load on the frontend.

Final Tips

Keep your Angular app modular so it can coexist with WordPress templates.

Use ng build –watch during development for quicker feedback.

Avoid overriding DOM content where WordPress needs control (like #wp-content).

You can optionally create a Gutenberg block in Angular using @wordpress/scripts, but that’s a more advanced setup.

Also Read:
Understanding Cookies in PHP

How to Create a PHP Session

Leave a Reply