\n\n```\n\n### 3. Test Different Hydration Strategies\n\nExperiment with different hydration strategies to find what works best in your micro-app environment:\n\n- `client:load` - Load and render immediately\n- `client:idle` - Load when browser is idle\n- `client:visible` - Load when component becomes visible\n- `client:only` - Client-side only rendering (with proper configuration)\n\n### 4. Monitor Performance\n\nUse browser dev tools to monitor:\n- JavaScript bundle size\n- Loading times\n- Hydration performance\n- Event handler attachment\n\n## Conclusion\n\nIntegrating an Astro + React application as a sub-application in a Vite + Vue3 + micro-app setup requires careful configuration and understanding of the unique challenges involved. The key takeaways are:\n\n1. **Configure Astro properly** for micro-app environments by adjusting Vite settings and React integration\n2. **Experiment with different hydration strategies** - `client:idle` may work better than `client:only` in micro-app scenarios\n3. **Adjust micro-app configuration** to handle Astro's island architecture requirements\n4. **Consider alternative approaches** like Module Federation or library builds if direct integration proves problematic\n5. **Test thoroughly** in your specific micro-app environment to ensure proper rendering and event handling\n\nThe core issue you're experiencing with `client:only=\"react\"` resulting in blank pages and `client:load` causing JavaScript loading failures stems from how Astro's hydration process interacts with the micro-app sandbox. By implementing the configuration changes and alternative approaches outlined above, you should be able to achieve a working integration between your Astro + React application and the Vite + Vue3 + micro-app setup.","@type":"Answer","url":"https://neuroanswers.net/q/astro-react-micro-app-integration#answer","dateCreated":"2025-11-06T01:28:30.766Z","dateModified":"2025-11-06T01:28:30.766Z","author":{"@type":"Organization","name":"Neurogram"}},"answerCount":1,"dateCreated":"2025-11-06T01:28:30.766Z","dateModified":"2025-11-06T01:28:30.766Z","author":{"@type":"Organization","name":"Neurogram"}},"mainEntityOfPage":{"@type":"WebPage","@id":"https://neuroanswers.net/q/astro-react-micro-app-integration"},"inLanguage":"en","publisher":{"@type":"Organization","name":"Neurogram","url":"https://neurogram.chat","logo":{"@type":"ImageObject","url":"https://neurogram.chat/logo-512x512.png"}},"breadcrumb":{"@type":"BreadcrumbList","itemListElement":[{"@type":"ListItem","position":1,"name":"NeuroAnswers","item":"https://neuroanswers.net"},{"@type":"ListItem","position":2,"name":"Astro + React Integration in Vite Vue3 Micro-Apps","item":"https://neuroanswers.net/q/astro-react-micro-app-integration"}]}}
NeuroAgent

Astro + React Integration in Vite Vue3 Micro-Apps

Learn how to integrate Astro + React applications as sub-applications in Vite + Vue3 + micro-app setups. Fix hydration conflicts and JavaScript loading issues with our comprehensive guide and practical solutions.

Question

How to integrate an Astro + React application as a sub-application in a Vite + Vue3 + micro-app setup?

I have a main application built with Vite + Vue3 + micro-app, and I need to integrate an Astro + React application as a sub-application. I’ve tried using the following approach:

html
<micro-app name='test' url='http://127.0.0.1:8000/workspace' iframe"/>

The sub-application is configured for cross-domain access, and the page uses:

html
<Layout>
  <Test client:only="react" />
</Layout>

My Test component contains:

javascript
const Test = () => {
  return (
    <>
      <h1>Test</h1>
      <Button onClick={console.log}>Click me3</Button>
    </>
  );
}

export default Test;

When using client:only="react" in the sub-application, I get a blank page with no content. When using client:load, click events don’t work, which suggests a JavaScript loading failure, leaving only the static page visible. Based on the current application elements, it appears that the micro-app is not properly hydrating the Astro Island as a client. What steps do I need to take to make Astro run correctly within the micro-app environment?

NeuroAgent

Astro + React integration with micro-app frameworks presents unique challenges due to hydration conflicts and JavaScript loading issues. The core problem lies in how Astro’s island architecture interacts with micro-app sandboxes, requiring specific configuration adjustments to ensure proper component rendering and event handling.


Contents


Understanding the Integration Challenge

When integrating an Astro + React application as a sub-application within a Vite + Vue3 + micro-app setup, you’re essentially trying to embed one web application within another. This creates several technical challenges:

  • Hydration conflicts: Astro’s server-side rendering (SSR) and client-side hydration mechanisms may not work correctly when the application is loaded within a micro-app sandbox
  • JavaScript loading: The micro-app environment may interfere with how Astro loads and executes React components
  • Context isolation: The React context and state management might not function properly when embedded

The micro-app framework creates an isolated environment for your Astro + React application, which can interfere with Astro’s normal hydration process. When you use client:only="react", Astro expects to handle the complete rendering and hydration process, but the micro-app may be interfering with this.

Core Issues with Astro Hydration in Micro-Apps

Based on the research findings, several specific issues emerge:

JavaScript Loading Failures

When using client:load, click events don’t work, indicating that JavaScript is loading but not executing properly within the micro-app environment. This suggests that the micro-app’s sandbox is preventing the JavaScript from running with the correct context.

Hydration Strategy Problems

The client:only="react" directive results in a blank page because Astro’s hydration process is designed to work within a normal browser environment, not within a micro-app sandbox. According to the research, Astro needs hints to use the correct renderer when using client:only hydration strategy, and this becomes more complex in micro-app scenarios.

React Root Creation Issues

A GitHub issue suggests that React components rendered with client:only should probably use createRoot instead of hydrateRoot, which may not be happening correctly in the micro-app environment.


Configuration Solutions for Astro

1. Modify Astro’s Vite Configuration

Update your astro.config.mjs to handle micro-app scenarios:

javascript
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';
import node from '@astrojs/node';

export default defineConfig({
  output: 'server',
  integrations: [react()],
  vite: {
    ssr: {
      noExternal: ['react', 'react-dom'], // Ensure React dependencies are bundled
    },
    build: {
      rollupOptions: {
        external: [], // Don't externalize anything for micro-app compatibility
      },
    },
    optimizeDeps: {
      force: true, // Force re-optimization for better compatibility
    },
  },
  adapter: node({
    mode: 'standalone',
  }),
});

2. Adjust React Component for Micro-App Environment

Modify your Test component to handle the micro-app environment:

javascript
import { useEffect, useRef } from 'react';

const Test = () => {
  const buttonRef = useRef(null);
  
  useEffect(() => {
    // Ensure React can properly attach event listeners
    if (buttonRef.current) {
      buttonRef.current.addEventListener('click', () => {
        console.log('Button clicked in micro-app environment');
      });
    }
  }, []);

  return (
    <>
      <h1>Test</h1>
      <Button ref={buttonRef}>Click me3</Button>
    </>
  );
}

export default Test;

3. Use Alternative Hydration Strategy

Consider using client:idle instead of client:only for better micro-app compatibility:

html
<Layout>
  <Test client:idle="react" />
</Layout>

The client:idle strategy renders the component only when the browser is idle, which may work better in micro-app environments.


Micro-App Environment Adjustments

1. Configure Micro-App for Astro Compatibility

Modify your micro-app configuration to better handle Astro’s requirements:

javascript
// In your main application
import microApp from '@micro-zoe/micro-app';

microApp.start({
  // Ensure proper communication with micro-app
  plugins: {
    // Add plugins to handle Astro's specific needs
  },
  // Disable some sandboxing features that might interfere with Astro
  sandbox: {
    // Adjust sandbox settings based on your needs
  },
});

2. Use iframe with Specific Attributes

Try different iframe configurations:

html
<micro-app 
  name='test' 
  url='http://127.0.0.1:8000/workspace' 
  iframe 
  shadowDom 
  inline 
  disableSandbox={false}
/>

The shadowDom and inline attributes may help with proper component rendering.

3. Enable Proper Communication Channels

Ensure proper communication between the main app and micro-app:

javascript
// In your Astro app
import { useEffect } from 'react';

const Test = () => {
  useEffect(() => {
    // Listen for micro-app events
    window.addEventListener('mount', () => {
      console.log('Micro-app mounted');
    });
    
    window.addEventListener('unmount', () => {
      console.log('Micro-app unmounted');
    });
  }, []);

  return (
    <>
      <h1>Test</h1>
      <Button onClick={() => console.log('Click me')}>Click me3</Button>
    </>
  );
}

Alternative Integration Approaches

1. Module Federation Integration

Consider using Module Federation to integrate Astro and React components:

javascript
// In your main Vite config
import { defineConfig } from 'vite';
import federation from '@originjs/vite-plugin-federation';

export default defineConfig({
  plugins: [
    federation({
      name: 'mainApp',
      remotes: {
        astroApp: 'http://localhost:8000/assets/remoteEntry.js',
      },
      shared: ['react', 'react-dom'],
    }),
  ],
});

2. Build Astro as a Library

Configure Astro to build as a library:

javascript
// astro.config.mjs
import { defineConfig } from 'astro/config';
import react from '@astrojs/react';

export default defineConfig({
  output: 'server',
  integrations: [react()],
  build: {
    format: 'esm',
  },
});

3. Use Static Islands for Better Compatibility

Consider using static Astro islands with React components:

html
---
import Test from '../components/Test.astro';
---

<Layout>
  <Test client:load />
</Layout>

Best Practices and Performance Considerations

1. Optimize Astro Build for Micro-Apps

javascript
// astro.config.mjs
export default defineConfig({
  output: 'server',
  integrations: [react()],
  vite: {
    ssr: {
      noExternal: ['react', 'react-dom', 'antd'], // Add any external dependencies
    },
    build: {
      target: 'esnext', // Use modern JavaScript features
    },
  },
});

2. Handle Resource Loading Properly

Ensure that all CSS and JavaScript resources are loaded correctly within the micro-app environment:

javascript
// In your Astro component
<head>
  <link rel="stylesheet" href="/styles.css" />
  <script type="module" src="/main.js"></script>
</head>

3. Test Different Hydration Strategies

Experiment with different hydration strategies to find what works best in your micro-app environment:

  • client:load - Load and render immediately
  • client:idle - Load when browser is idle
  • client:visible - Load when component becomes visible
  • client:only - Client-side only rendering (with proper configuration)

4. Monitor Performance

Use browser dev tools to monitor:

  • JavaScript bundle size
  • Loading times
  • Hydration performance
  • Event handler attachment

Conclusion

Integrating an Astro + React application as a sub-application in a Vite + Vue3 + micro-app setup requires careful configuration and understanding of the unique challenges involved. The key takeaways are:

  1. Configure Astro properly for micro-app environments by adjusting Vite settings and React integration
  2. Experiment with different hydration strategies - client:idle may work better than client:only in micro-app scenarios
  3. Adjust micro-app configuration to handle Astro’s island architecture requirements
  4. Consider alternative approaches like Module Federation or library builds if direct integration proves problematic
  5. Test thoroughly in your specific micro-app environment to ensure proper rendering and event handling

The core issue you’re experiencing with client:only="react" resulting in blank pages and client:load causing JavaScript loading failures stems from how Astro’s hydration process interacts with the micro-app sandbox. By implementing the configuration changes and alternative approaches outlined above, you should be able to achieve a working integration between your Astro + React application and the Vite + Vue3 + micro-app setup.

Sources

  1. Astro Documentation - React Integration
  2. Stack Overflow - How to run an Astro web application as a sub-application into a micro-app
  3. GitHub Issue - React component hydration error when loaded with client:only
  4. Medium - Setting up micro-frontends with Astro and Ecma Script Modules
  5. Leapcell - Seamless Integration of React and Vue Applications in Astro Using Module Federation